- Timestamp:
- Apr 13, 2008, 9:59:55 PM (17 years ago)
- Location:
- trunk/src
- Files:
-
- 1 added
- 15 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/cutest_slib.c
r21 r169 24 24 } 25 25 26 void Test_sl_strcasecmp (CuTest *tc) { 27 char one[64], two[64]; 28 int res; 26 29 30 strcpy(one, "foo"); 31 strcpy(two, "foo"); 32 res = sl_strcasecmp(one, two); 33 CuAssertIntEquals(tc, 0, res); 34 35 strcpy(one, "fo"); 36 strcpy(two, "foo"); 37 res = sl_strcasecmp(one, two); 38 CuAssertIntEquals(tc, -1, res); 39 40 strcpy(one, "foo"); 41 strcpy(two, "fo"); 42 res = sl_strcasecmp(one, two); 43 CuAssertIntEquals(tc, 1, res); 44 45 strcpy(one, "1234"); 46 strcpy(two, "2345"); 47 res = sl_strcasecmp(one, two); 48 CuAssertIntEquals(tc, -1, res); 49 50 strcpy(one, "234"); 51 strcpy(two, "123"); 52 res = sl_strcasecmp(one, two); 53 CuAssertIntEquals(tc, 1, res); 54 55 strcpy(one, ""); 56 strcpy(two, "123"); 57 res = sl_strcasecmp(one, two); 58 CuAssertIntEquals(tc, -1, res); 59 60 strcpy(one, "234"); 61 strcpy(two, ""); 62 res = sl_strcasecmp(one, two); 63 CuAssertIntEquals(tc, 1, res); 64 65 strcpy(one, ""); 66 strcpy(two, ""); 67 res = sl_strcasecmp(one, two); 68 CuAssertTrue(tc, res == 0); 69 70 #ifndef SL_FAIL_ON_ERROR 71 res = sl_strcasecmp(NULL, two); 72 CuAssertIntEquals(tc, -1, res); 73 74 res = sl_strcasecmp(one, NULL); 75 CuAssertIntEquals(tc, 1, res); 76 77 res = sl_strcasecmp(NULL, NULL); 78 CuAssertTrue(tc, res != 0); 79 #endif 80 } -
trunk/src/samhain.c
r162 r169 775 775 */ 776 776 (void) sh_unix_rm_lock_file (sh.srvlog.name); 777 (void) sh_unix_rm_pid_file (); 777 if (sh.flag.isdaemon == S_TRUE) 778 (void) sh_unix_rm_pid_file (); 778 779 if (skey != NULL) 779 780 memset (skey, (int) '\0', sizeof(sh_key_t)); -
trunk/src/sh_calls.c
r137 r169 341 341 #endif 342 342 343 SL_ENTER(_("retry_ fcntl"));343 SL_ENTER(_("retry_msleep")); 344 344 345 345 errno = 0; -
trunk/src/sh_cat.c
r144 r169 134 134 135 135 #ifdef SH_USE_PORTCHECK 136 { MSG_PORT_REPORT, SH_ERR_SEVERE, EVENT, N_("msg=\"%s\"")}, 136 { MSG_PORT_MISS, SH_ERR_SEVERE, EVENT, N_("msg=\"POLICY [ServiceMissing] %s\"")}, 137 { MSG_PORT_NEW, SH_ERR_SEVERE, EVENT, N_("msg=\"POLICY [ServiceNew] %s\"")}, 138 { MSG_PORT_RESTART,SH_ERR_SEVERE, EVENT, N_("msg=\"POLICY [ServiceRestarted] %s\"")}, 139 { MSG_PORT_NEWPORT,SH_ERR_SEVERE, EVENT, N_("msg=\"POLICY [ServicePortSwitch] %s\"")}, 137 140 #endif 138 141 … … 449 452 450 453 #ifdef SH_USE_PORTCHECK 451 { MSG_PORT_REPORT, SH_ERR_SEVERE, EVENT, N_("msg=<%s>")}, 454 { MSG_PORT_MISS, SH_ERR_SEVERE, EVENT, N_("msg=<POLICY [ServiceMissing] %s>")}, 455 { MSG_PORT_NEW, SH_ERR_SEVERE, EVENT, N_("msg=<POLICY [ServiceNew] %s>")}, 456 { MSG_PORT_RESTART,SH_ERR_SEVERE, EVENT, N_("msg=<POLICY [ServiceRestarted] %s>")}, 457 { MSG_PORT_NEWPORT,SH_ERR_SEVERE, EVENT, N_("msg=<POLICY [ServicePortSwitch] %s>")}, 452 458 #endif 453 459 -
trunk/src/sh_extern.c
r164 r169 143 143 * -- check whether path is trustworthy 144 144 */ 145 status = sl_trustfile(task->command, NULL, NULL); 146 #if 0 145 147 if ((uid_t) -1 != task->trusted_users[0]) 146 148 { 147 149 status = sl_trustfile(task->command, task->trusted_users, NULL); 148 150 } 151 #endif 149 152 150 153 PDBG_OPEN; … … 647 650 tas->argv[i] = NULL; 648 651 tas->envv[i] = NULL; 652 #if 0 649 653 tas->trusted_users[i] = (uid_t) -1; 654 #endif 650 655 } 651 656 … … 826 831 827 832 (void) sl_get_euid(&ff_euid); 833 #if 0 828 834 ext_com->tas.trusted_users[0] = (uid_t) 0; 829 835 ext_com->tas.trusted_users[1] = (uid_t) (ff_euid); 836 #endif 830 837 831 838 /* ------------------------------------------------- */ -
trunk/src/sh_getopt.c
r161 r169 225 225 HAS_ARG_NO, 226 226 sh_getopt_forever}, 227 { N_("list-file"), 228 '-', 229 N_("Modify -d to list content of a single file"), 230 HAS_ARG_YES, 231 set_list_file}, 227 232 { N_("full-detail"), 228 233 'a', … … 417 422 #if defined(SL_DEBUG) 418 423 if (num > 0) fputc ('\n', stdout); 419 fputs (_(" debug build "), stdout); ++num;424 fputs (_(" debug build (don't use for production)"), stdout); ++num; 420 425 #endif 421 426 #if defined(SCREW_IT_UP) … … 433 438 434 439 #if defined(SH_WITH_CLIENT) || defined(SH_STANDALONE) 440 #if defined(HAVE_LIBZ) 441 if (num > 0) fputc ('\n', stdout); 442 fputs (_(" optionally store full text for files"), stdout); ++num; 443 #endif 435 444 #if defined(USE_XATTR) 436 445 if (num > 0) fputc ('\n', stdout); -
trunk/src/sh_hash.c
r167 r169 2497 2497 sl_strlcat(msg, tmp, SH_BUFSIZE); 2498 2498 2499 if (theFile->c_mode[0] == 'l' || theFile->link_path != NULL) 2499 if (theFile->c_mode[0] == 'l' || 2500 (theFile->link_path != NULL && theFile->link_path[0] != '-')) 2500 2501 { 2501 2502 tmp_lnk = sh_util_safe_name(theFile->link_path); … … 2663 2664 sl_strlcat(msg, tmp, SH_BUFSIZE); 2664 2665 2665 if (theFile->c_mode[0] == 'l' || theFile->link_path != NULL) 2666 if (theFile->c_mode[0] == 'l' || 2667 (theFile->link_path != NULL && theFile->link_path[0] != '-')) 2666 2668 { 2667 2669 tmp_lnk = sh_util_safe_name(theFile->link_path); … … 2739 2741 char timstr2m[32]; 2740 2742 char linkHash[KEY_LEN+1]; 2743 char * linkComp; 2741 2744 int maxcomp; 2742 2745 … … 2869 2872 if (p->theFile.c_mode[0] == 'l') 2870 2873 { 2871 if (sl_strlen(theFile->link_path) >= MAX_PATH_STORE) 2872 { 2873 sl_strlcpy(linkHash, 2874 sh_tiger_hash(theFile->link_path, 2875 TIGER_DATA, 2876 sl_strlen(theFile->link_path), 2877 hashbuf, sizeof(hashbuf)), 2878 MAX_PATH_STORE+1); 2879 maxcomp = MAX_PATH_STORE; 2880 } 2881 else 2882 { 2883 sl_strlcpy(linkHash, theFile->link_path, KEY_LEN + 1); 2884 maxcomp = KEY_LEN; 2885 } 2886 2887 2888 if ( sl_strncmp (linkHash, p->linkpath, maxcomp) != 0 && 2889 (theFile->check_mask & MODI_LNK) != 0) 2890 { 2874 if (!(theFile->link_path) && 2875 (theFile->check_mask & MODI_LNK) != 0) 2876 { 2877 linkComp = NULL; 2891 2878 modi_mask |= MODI_LNK; 2892 2879 change_code[1] = 'L'; 2893 2880 TPT ((0, FIL__, __LINE__, _("mod=<link>"))); 2894 } 2881 } 2882 else 2883 { 2884 if (sl_strlen(theFile->link_path) >= MAX_PATH_STORE) 2885 { 2886 sl_strlcpy(linkHash, 2887 sh_tiger_hash(theFile->link_path, 2888 TIGER_DATA, 2889 sl_strlen(theFile->link_path), 2890 hashbuf, sizeof(hashbuf)), 2891 MAX_PATH_STORE+1); 2892 linkComp = linkHash; 2893 maxcomp = KEY_LEN; 2894 } 2895 else 2896 { 2897 linkComp = theFile->link_path; 2898 maxcomp = MAX_PATH_STORE; 2899 } 2900 2901 if ( sl_strncmp (linkComp, p->linkpath, maxcomp) != 0 && 2902 (theFile->check_mask & MODI_LNK) != 0) 2903 { 2904 modi_mask |= MODI_LNK; 2905 change_code[1] = 'L'; 2906 TPT ((0, FIL__, __LINE__, _("mod=<link>"))); 2907 } 2908 } 2895 2909 } 2896 2910 … … 3349 3363 } 3350 3364 #endif 3351 } 3352 3353 3354 if ((modi_mask & MODI_LNK) != 0 && theFile->c_mode[0] == 'l') 3355 { 3356 tmp_lnk = sh_util_safe_name(theFile->link_path); 3357 tmp_lnk_old = sh_util_safe_name(p->linkpath); 3365 /* FIXME is this correct? */ 3366 if (theFile->c_mode[0] != 'l' && theFile->link_path && 3367 strlen(theFile->link_path) > 2) 3368 modi_mask |= MODI_LNK; 3369 } 3370 3371 3372 if ((modi_mask & MODI_LNK) != 0 /* && theFile->c_mode[0] == 'l' */) 3373 { 3374 if (theFile->link_path) 3375 tmp_lnk = sh_util_safe_name(theFile->link_path); 3376 else 3377 tmp_lnk = sh_util_strdup("-"); 3378 if (p->linkpath) 3379 tmp_lnk_old = sh_util_safe_name(p->linkpath); 3380 else 3381 tmp_lnk_old = sh_util_strdup("-"); 3358 3382 #ifdef SH_USE_XML 3359 3383 sl_snprintf(tmp, SH_BUFSIZE, _("link_old=\"%s\" link_new=\"%s\" "), … … 3599 3623 #endif 3600 3624 3601 static int ListFullDetail = S_FALSE;3625 static int ListFullDetail = S_FALSE; 3602 3626 static int ListWithDelimiter = S_FALSE; 3627 static char * ListFile = NULL; 3628 3629 int set_list_file (const char * c) 3630 { 3631 ListFile = sh_util_strdup(c); 3632 return 0; 3633 } 3603 3634 3604 3635 int set_full_detail (const char * c) … … 3858 3889 } 3859 3890 3891 #ifdef HAVE_LIBZ 3892 #include <zlib.h> 3893 #endif 3894 3895 int sh_hash_printcontent(char * linkpath) 3896 { 3897 #ifdef HAVE_LIBZ 3898 unsigned char * decoded; 3899 unsigned char * decompressed = NULL; 3900 size_t dlen; 3901 unsigned long clen; 3902 unsigned long clen_o; 3903 int res; 3904 3905 if (linkpath && *linkpath != '-') 3906 { 3907 dlen = sh_util_base64_dec_alloc (&decoded, 3908 (unsigned char *)linkpath, 3909 strlen(linkpath)); 3910 clen = dlen * 2 + 1; 3911 do { 3912 if (decompressed) 3913 SH_FREE(decompressed); 3914 clen += dlen; clen_o = clen; 3915 decompressed = SH_ALLOC(clen); 3916 res = uncompress(decompressed, &clen, decoded, dlen); 3917 if (res == Z_MEM_ERROR) 3918 { fprintf(stderr, _("Error: Not enough memory\n")); return -1; } 3919 if (res == Z_DATA_ERROR) 3920 { fprintf(stderr, _("Error: Data corrupt or incomplete\n")); return -1; } 3921 } while (res == Z_BUF_ERROR || clen == clen_o); 3922 decompressed[clen] = '\0'; 3923 fputs( (char*) decompressed, stdout); 3924 return 0; 3925 } 3926 #else 3927 (void) linkpath; 3928 #endif 3929 fprintf(stderr, _("Error: No data available\n")); 3930 return -1; 3931 } 3932 3860 3933 int sh_hash_list_db (const char * db_file) 3861 3934 { … … 3863 3936 SL_TICKET fd; 3864 3937 char * line; 3938 int flag = 0; 3865 3939 3866 3940 if (!db_file) … … 3900 3974 { 3901 3975 p = sh_hash_getdataent (fd, line, MAX_PATH_STORE); 3902 if ((p != NULL) && (p->fullpath[0] != 'K')) 3903 { 3904 if (ListFullDetail == S_FALSE) 3905 sh_hash_list_db_entry (p); 3976 if ((p != NULL) && (p->fullpath[0] == '/')) 3977 { 3978 if (!ListFile) 3979 { 3980 flag = 1; 3981 if (ListFullDetail == S_FALSE) 3982 sh_hash_list_db_entry (p); 3983 else 3984 sh_hash_list_db_entry_full_detail (p); 3985 } 3906 3986 else 3907 sh_hash_list_db_entry_full_detail (p); 3987 { 3988 if (0 != sl_strcmp(ListFile, p->fullpath)) 3989 { 3990 continue; 3991 } 3992 flag = 1; 3993 if ('l' != p->theFile.c_mode[0]) 3994 { 3995 if (sh_hash_printcontent(p->linkpath) < 0) 3996 { 3997 _exit(EXIT_FAILURE); 3998 return -1; 3999 } 4000 } 4001 else 4002 { 4003 fprintf(stderr, _("File is a link\n")); 4004 _exit(EXIT_FAILURE); 4005 return -1; 4006 } 4007 break; 4008 } 3908 4009 } 3909 4010 else if (p == NULL) … … 3919 4020 fflush(NULL); 3920 4021 4022 if (flag == 0) 4023 { 4024 fprintf(stderr, _("No file found\n")); 4025 _exit(EXIT_FAILURE); 4026 } 3921 4027 _exit(EXIT_SUCCESS); 3922 4028 return 0; -
trunk/src/sh_mounts.c
r149 r169 180 180 } 181 181 182 lastcheck = time(NULL);183 184 182 SL_RETURN(0, _("sh_mounts_init")); 185 183 } … … 197 195 SL_RETURN(-1, _("sh_mounts_timer")); 198 196 } 199 197 200 198 SL_RETURN(0, _("sh_mounts_timer")); 201 199 } … … 400 398 401 399 /* FreeBSD includes */ 402 #if def HOST_IS_FREEBSD400 #if defined(HOST_IS_FREEBSD) || defined(HOST_IS_OPENBSD) 403 401 #include <sys/param.h> 404 402 #include <sys/ucred.h> … … 577 575 #endif 578 576 579 #if defined(HOST_IS_FREEBSD) 577 #if defined(HOST_IS_FREEBSD) || defined(HOST_IS_OPENBSD) 580 578 581 579 /* FreeBSD returns flags instead of strings as mount options, so we'll convert … … 595 593 {"local", MNT_LOCAL}, 596 594 {"quota", MNT_QUOTA}, 595 #ifdef MNT_NOATIME 596 {"noatime", MNT_NOATIME}, 597 #endif 597 598 {"bound", -1} 598 599 }; … … 665 666 list = m; 666 667 667 /* The FreeBSD way */668 #if def HOST_IS_FREEBSD668 /* The Open/FreeBSD way */ 669 #if defined(HOST_IS_FREEBSD) || defined(HOST_IS_OPENBSD) 669 670 { 670 671 struct statfs *fsp; -
trunk/src/sh_portcheck.c
r162 r169 384 384 if (ptr->flag != SH_PORT_OPT && ptr->flag != SH_PORT_IGN) 385 385 { 386 snprintf (errbuf, sizeof(errbuf), _(" POLICY [ServiceMissing] port%s:%d/%s (%s)"),386 snprintf (errbuf, sizeof(errbuf), _("port: %s:%d/%s (%s)"), 387 387 ptr->interface, ptr->port, SH_PROTO_STR(proto), 388 388 ptr->service ? ptr->service : check_services(ptr->port, proto)); … … 395 395 SH_MUTEX_LOCK(mutex_thread_nolog); 396 396 sh_error_handle(sh_portchk_severity, FIL__, __LINE__, 0, 397 MSG_PORT_ REPORT, errbuf);397 MSG_PORT_MISS, errbuf); 398 398 SH_MUTEX_UNLOCK(mutex_thread_nolog); 399 399 } … … 497 497 if (!portent) 498 498 { 499 snprintf (errbuf, sizeof(errbuf), _(" POLICY [ServiceNew] port%s:%d/%s (%s)"),499 snprintf (errbuf, sizeof(errbuf), _("port: %s:%d/%s (%s)"), 500 500 inet_ntoa(haddr), port, SH_PROTO_STR(proto), service); 501 501 #ifdef TEST_ONLY … … 505 505 SH_MUTEX_LOCK(mutex_thread_nolog); 506 506 sh_error_handle(sh_portchk_severity, FIL__, __LINE__, 0, 507 MSG_PORT_ REPORT, errbuf);507 MSG_PORT_NEW, errbuf); 508 508 SH_MUTEX_UNLOCK(mutex_thread_nolog); 509 509 #endif … … 515 515 else if (portent->status == SH_PORT_MISS && portent->flag != SH_PORT_IGN) 516 516 { 517 snprintf (errbuf, sizeof(errbuf), _(" POLICY [ServiceRestarted] port %s:%d/%s to %d/%s (%s)"),518 inet_ntoa(haddr), port ent->port, SH_PROTO_STR(proto), port, SH_PROTO_STR(proto), service);517 snprintf (errbuf, sizeof(errbuf), _("port: %s:%d/%s (%s), was %d/%s"), 518 inet_ntoa(haddr), port, SH_PROTO_STR(proto), service, portent->port, SH_PROTO_STR(proto)); 519 519 #ifdef TEST_ONLY 520 520 fprintf(stderr, _("service: %s\n"), errbuf); … … 522 522 SH_MUTEX_LOCK(mutex_thread_nolog); 523 523 sh_error_handle(sh_portchk_severity, FIL__, __LINE__, 0, 524 MSG_PORT_RE PORT, errbuf);524 MSG_PORT_RESTART, errbuf); 525 525 SH_MUTEX_UNLOCK(mutex_thread_nolog); 526 526 #endif … … 530 530 else if (port != portent->port && (-1) != portent->port) 531 531 { 532 snprintf (errbuf, sizeof(errbuf), _(" POLICY [ServicePortSwitch] port %s:%d/%s to %d/%s (%s)"),533 inet_ntoa(haddr), port ent->port, SH_PROTO_STR(proto), port, SH_PROTO_STR(proto), service);532 snprintf (errbuf, sizeof(errbuf), _("port: %s:%d/%s (%s), was %d/%s"), 533 inet_ntoa(haddr), port, SH_PROTO_STR(proto), service, portent->port, SH_PROTO_STR(proto)); 534 534 #ifdef TEST_ONLY 535 535 fprintf(stderr, _("service: %s\n"), errbuf); … … 537 537 SH_MUTEX_LOCK(mutex_thread_nolog); 538 538 sh_error_handle(sh_portchk_severity, FIL__, __LINE__, 0, 539 MSG_PORT_ REPORT, errbuf);539 MSG_PORT_NEWPORT, errbuf); 540 540 SH_MUTEX_UNLOCK(mutex_thread_nolog); 541 541 #endif … … 552 552 if (!portent) 553 553 { 554 snprintf (errbuf, sizeof(errbuf), _(" POLICY [ServiceNew] port%s:%d/%s (%s)"),554 snprintf (errbuf, sizeof(errbuf), _("port: %s:%d/%s (%s)"), 555 555 inet_ntoa(haddr), port, SH_PROTO_STR(proto), check_services(port, proto)); 556 556 #ifdef TEST_ONLY … … 560 560 SH_MUTEX_LOCK(mutex_thread_nolog); 561 561 sh_error_handle(sh_portchk_severity, FIL__, __LINE__, 0, 562 MSG_PORT_ REPORT, errbuf);562 MSG_PORT_NEW, errbuf); 563 563 SH_MUTEX_UNLOCK(mutex_thread_nolog); 564 564 #endif … … 570 570 else if (portent->status == SH_PORT_MISS && portent->flag != SH_PORT_IGN) 571 571 { 572 snprintf (errbuf, sizeof(errbuf), _(" POLICY [ServiceRestarted] port%s:%d/%s (%s)"),572 snprintf (errbuf, sizeof(errbuf), _("port: %s:%d/%s (%s)"), 573 573 inet_ntoa(haddr), port, SH_PROTO_STR(proto), check_services(port, proto)); 574 574 #ifdef TEST_ONLY … … 577 577 SH_MUTEX_LOCK(mutex_thread_nolog); 578 578 sh_error_handle(sh_portchk_severity, FIL__, __LINE__, 0, 579 MSG_PORT_RE PORT, errbuf);579 MSG_PORT_RESTART, errbuf); 580 580 SH_MUTEX_UNLOCK(mutex_thread_nolog); 581 581 #endif -
trunk/src/sh_prelude.c
r131 r169 85 85 #define SH_NEED_PWD_GRP 1 86 86 #include "sh_static.h" 87 87 char * sh_util_strdup (const char * str) SH_GNUC_MALLOC; 88 88 /* 89 89 * When SH_USE_XML is set, value are formated using name="value". … … 651 651 #endif 652 652 653 #ifdef SH_USE_PORTCHECK 654 { MSG_PORT_MISS, N_("Service closed"), IDMEF_IMPACT_TYPE_OTHER }, 655 { MSG_PORT_NEW, N_("Service opened"), IDMEF_IMPACT_TYPE_OTHER }, 656 { MSG_PORT_RESTART, N_("Service restarted"), IDMEF_IMPACT_TYPE_OTHER }, 657 { MSG_PORT_NEWPORT, N_("Service restarted"), IDMEF_IMPACT_TYPE_OTHER }, 658 #endif 659 653 660 #ifdef SH_USE_SUIDCHK 654 661 { MSG_SUID_POLICY, N_("SUID/SGID File Detected"), IDMEF_IMPACT_TYPE_FILE }, … … 684 691 685 692 693 #ifdef SH_USE_PORTCHECK 694 static int get_service_info(char *msg, idmef_alert_t *alert) 695 { 696 int ret; 697 long port; 698 char *ptr, *new, *tmp, *ip, *srv, *end; 699 prelude_string_t *str; 700 idmef_address_t *address; 701 idmef_node_t *node; 702 idmef_service_t *service; 703 idmef_source_t *source = idmef_alert_get_next_source(alert, NULL); 704 705 new = sh_util_strdup(msg); 706 707 ptr = strstr(new, _("port: ")); 708 if ( ! ptr ) { 709 sh_error_handle((-1), FIL__, __LINE__, -1, MSG_E_SUBGEN, 710 _("malformed Samhain port check message"), _("get_service_info")); 711 SH_FREE( new ); 712 return -1; 713 } 714 715 ptr += 6; /* skip 'port: ', position on first byte of interface */ 716 tmp = strchr(ptr, ':'); 717 if ( ! tmp ) { 718 sh_error_handle((-1), FIL__, __LINE__, -1, MSG_E_SUBGEN, 719 _("malformed Samhain port check message (no port)"), _("get_service_info")); 720 SH_FREE( new ); 721 return -1; 722 } 723 *tmp = '\0'; 724 725 ip = strdup(ptr); 726 if ( ip ) { 727 if ( ! source ) { 728 ret = idmef_alert_new_source(alert, &source, IDMEF_LIST_APPEND); 729 if ( ret < 0 ) { 730 free(ip); 731 SH_FREE( new ); 732 return ret; 733 } 734 } 735 736 ret = idmef_source_new_node(source, &node); 737 if ( ret < 0 ) { 738 free(ip); 739 SH_FREE( new ); 740 return ret; 741 } 742 743 ret = idmef_node_new_address(node, &address, IDMEF_LIST_APPEND); 744 if ( ret < 0 ) { 745 free(ip); 746 SH_FREE( new ); 747 return ret; 748 } 749 750 ret = idmef_address_new_address(address, &str); 751 if ( ret < 0 ) { 752 free(ip); 753 SH_FREE( new ); 754 return ret; 755 } 756 757 prelude_string_set_nodup(str, ip); 758 } 759 760 ptr = tmp; 761 ++ptr; 762 tmp = strchr(ptr, '/'); 763 if ( ! tmp ) { 764 sh_error_handle((-1), FIL__, __LINE__, -1, MSG_E_SUBGEN, 765 _("malformed Samhain port check message (no protocol)"), _("get_service_info")); 766 SH_FREE( new ); 767 return -1; 768 } 769 *tmp = '\0'; 770 771 port = strtol(ptr, &end, 0); 772 if ( *ptr && *end == '\0' && port >= 0 && port < 65536) { 773 774 if ( ! source ) { 775 ret = idmef_alert_new_source(alert, &source, IDMEF_LIST_APPEND); 776 if ( ret < 0 ) { 777 free(srv); 778 SH_FREE( new ); 779 return ret; 780 } 781 } 782 783 ret = idmef_source_new_service(source, &service); 784 if ( ret < 0 ) { 785 free(srv); 786 SH_FREE( new ); 787 return ret; 788 } 789 790 idmef_service_set_port(service, port); 791 } 792 793 ptr = tmp; 794 ++ptr; 795 ptr = strchr(ptr, '('); 796 if ( ! ptr ) { 797 sh_error_handle((-1), FIL__, __LINE__, -1, MSG_E_SUBGEN, 798 _("malformed Samhain port check message (no service)"), _("get_service_info")); 799 SH_FREE( new ); 800 return -1; 801 } 802 ++ptr; 803 tmp = strchr(ptr, ')'); 804 if ( ! tmp ) { 805 sh_error_handle((-1), FIL__, __LINE__, -1, MSG_E_SUBGEN, 806 _("malformed Samhain port check message (service not closed)"), _("get_service_info")); 807 SH_FREE( new ); 808 return -1; 809 } 810 *tmp = '\0'; 811 812 srv = strdup(ptr); 813 if ( srv ) { 814 if ( ! source ) { 815 ret = idmef_alert_new_source(alert, &source, IDMEF_LIST_APPEND); 816 if ( ret < 0 ) { 817 free(srv); 818 SH_FREE( new ); 819 return ret; 820 } 821 } 822 823 if ( ! service ) { 824 ret = idmef_source_new_service(source, &service); 825 if ( ret < 0 ) { 826 free(srv); 827 SH_FREE( new ); 828 return ret; 829 } 830 } 831 832 ret = idmef_service_new_ident(service, &str); 833 if ( ret < 0 ) { 834 free(srv); 835 SH_FREE( new ); 836 return ret; 837 } 838 839 prelude_string_set_nodup(str, srv); 840 } 841 842 SH_FREE( new ); 843 844 return 0; 845 } 846 #endif 686 847 687 848 static int get_login_info(char *msg, idmef_alert_t *alert) … … 902 1063 goto err; 903 1064 1065 #ifdef SH_USE_PORTCHECK 1066 if (msgid == MSG_PORT_MISS || msgid == MSG_PORT_NEW || msgid == MSG_PORT_RESTART || msgid == MSG_PORT_NEWPORT) { 1067 ret = get_service_info(message, alert); 1068 if ( ret < 0 ) 1069 goto err; 1070 } 1071 #endif 1072 904 1073 map_policy_to_class(message, msgid, impact, str); 905 1074 -
trunk/src/sh_processcheck.c
r144 r169 837 837 else if (errno == EAGAIN) 838 838 { 839 clearerr(in); 839 840 continue; 840 841 } 842 #ifdef HOST_IS_OPENBSD 843 else if (errno == ENODEV) 844 { 845 clearerr(in); 846 continue; 847 } 848 #endif 841 849 else 842 850 { … … 1049 1057 size_t i, j; 1050 1058 char tests[512]; 1059 int retval; 1051 1060 1052 1061 pid_t this_pid; … … 1060 1069 SH_MUTEX_LOCK(mutex_thread_nolog); 1061 1070 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_E_SUBGEN, 1062 _("Internal error: NULL argument "),1071 _("Internal error: NULL argument, switching off"), 1063 1072 _("sh_process_check_int")); 1064 1073 SH_MUTEX_UNLOCK(mutex_thread_nolog); … … 1067 1076 1068 1077 SH_MUTEX_LOCK(mutex_thread_nolog); 1069 sh_processes_runps (res, NULL, 0, SH_PR_PS, 0);1078 retval = sh_processes_runps (res, NULL, 0, SH_PR_PS, 0); 1070 1079 SH_MUTEX_UNLOCK(mutex_thread_nolog); 1071 1080 for (i = sh_prochk_minpid; i != sh_prochk_maxpid; ++i) … … 1075 1084 } 1076 1085 SH_MUTEX_LOCK(mutex_thread_nolog); 1077 sh_processes_runps (res, NULL, 0, SH_PR_PS2, 0);1086 retval += sh_processes_runps (res, NULL, 0, SH_PR_PS2, 0); 1078 1087 SH_MUTEX_UNLOCK(mutex_thread_nolog); 1088 1089 if (retval != 0) 1090 { 1091 SH_MUTEX_LOCK(mutex_thread_nolog); 1092 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_E_SUBGEN, 1093 _("Failed to run ps, switching off"), 1094 _("sh_process_check_int")); 1095 SH_MUTEX_UNLOCK(mutex_thread_nolog); 1096 SL_RETURN ((-1), _("sh_process_check_int")); 1097 } 1079 1098 1080 1099 /* Evaluate results -
trunk/src/sh_readconf.c
r164 r169 573 573 */ 574 574 sl_rewind (fd); 575 sh_error_only_stderr (S_FALSE);576 575 if (0 != sh_gpg_check_sign (fd, 0, 1)) 577 576 aud_exit (FIL__, __LINE__, EXIT_FAILURE); -
trunk/src/sh_tools.c
r161 r169 582 582 *errnum = 0; 583 583 if (sl_strlen(host_entry->h_name) == 0 || 584 (*errnum = sl_strc mp(host_name,host_entry->h_name)) != 0)584 (*errnum = sl_strcasecmp(host_name,host_entry->h_name)) != 0) 585 585 { 586 586 if (*errnum) … … 1663 1663 SH_FREE (file); 1664 1664 SH_FREE(my_tmp_dir); 1665 sh_error_handle(SH_ERR_ALL, FIL__, __LINE__, status, MSG_E_SUBGEN, 1666 _("Error (lstat) while opening temporary file"), _("open_tmp")); 1665 1667 TPT(( 0, FIL__, __LINE__, _("msg=<Unexpected error %d>\n"), error)); 1666 1668 SL_RETURN((-1), _("open_tmp")); -
trunk/src/sh_unix.c
r167 r169 43 43 #include <fcntl.h> 44 44 #include <unistd.h> 45 /* need to undef these, since the #define's may be picked up from 46 * linux/wait.h, and will clash with a typedef in sys/wait.h 47 */ 48 #undef P_ALL 49 #undef P_PID 50 #undef P_PGID 45 51 #include <sys/wait.h> 46 52 … … 2993 2999 someval *= 1000; /* milliseconds in a second */ 2994 3000 sometime = (unsigned long) someval; 2995 /* fprintf(stderr, "FIXME PAUSE %ld\n", sometime); */2996 3001 retry_msleep(0, sometime); 2997 3002 } … … 2999 3004 { 3000 3005 sometime = (unsigned long) someval; 3001 /* fprintf(stderr, "FIXME PAUSE %ld sec\n", sometime); */3002 3006 retry_msleep (sometime, 0); 3003 3007 } … … 3037 3041 3038 3042 SL_ENTER(_("sh_unix_checksum_size")); 3043 3044 tmpFile.link_path = NULL; 3039 3045 3040 3046 if (sh.flag.checkSum != SH_CHECK_INIT) … … 3256 3262 } 3257 3263 #endif 3258 3264 3265 #ifdef HAVE_LIBZ 3266 #include <zlib.h> 3267 #endif 3259 3268 3260 3269 int sh_unix_getinfo (int level, char * filename, file_type * theFile, … … 3402 3411 UINT64 length_nolim = TIGER_NOLIM; 3403 3412 3404 if ((theFile->check_mask & MODI_TXT) != 0 && fbuf.st_size < SH_TXT_MAX)3413 if ((theFile->check_mask & MODI_TXT) != 0 && fbuf.st_size < (10 * SH_TXT_MAX)) 3405 3414 { 3406 3415 sl_init_content (rval_open, fbuf.st_size); … … 3415 3424 3416 3425 content = sl_get_content(rval_open); 3426 content = sh_string_copy(content); 3417 3427 3418 3428 if ((theFile->check_mask & MODI_SGROW) != 0) … … 3454 3464 UINT64 length_nolim = TIGER_NOLIM; 3455 3465 3456 if ((theFile->check_mask & MODI_TXT) != 0 && fbuf.st_size < SH_TXT_MAX)3466 if ((theFile->check_mask & MODI_TXT) != 0 && fbuf.st_size < (10 * SH_TXT_MAX)) 3457 3467 { 3458 3468 sl_init_content (rval_open, fbuf.st_size); … … 3467 3477 3468 3478 content = sl_get_content(rval_open); 3479 content = sh_string_copy(content); 3469 3480 3470 3481 if ((theFile->check_mask & MODI_SGROW) != 0) … … 3759 3770 if (content) 3760 3771 { 3761 sh_util_base64_enc_alloc (&(theFile->link_path), 3762 sh_string_str(content), 3763 sh_string_len(content)); 3772 #ifdef HAVE_LIBZ 3773 unsigned long clen = compressBound(sh_string_len(content)); 3774 unsigned char * compressed = SH_ALLOC(clen); 3775 if (Z_OK == compress(compressed, &clen, 3776 (unsigned char *) sh_string_str(content), 3777 sh_string_len(content))) 3778 { 3779 if (clen < SH_TXT_MAX) 3780 { 3781 sh_util_base64_enc_alloc (&(theFile->link_path), 3782 (char *) compressed, clen); 3783 } 3784 else 3785 { 3786 char tmsg[128]; 3787 char * tpath = sh_util_safe_name (theFile->fullpath); 3788 sl_snprintf(tmsg, sizeof(tmsg), 3789 _("compressed file too large (%lu bytes)"), 3790 clen); 3791 sh_error_handle (SH_ERR_WARN, FIL__, __LINE__, -1, 3792 MSG_E_SUBGPATH, tmsg, 3793 _("sh_unix_getinfo"), tpath); 3794 SH_FREE(tpath); 3795 } 3796 } 3797 SH_FREE(compressed); 3798 #endif 3799 sh_string_destroy(&content); 3764 3800 } 3765 3801 } … … 3770 3806 #endif 3771 3807 3772 int sh_unix_unlock (char * lockfile, char * flag); 3773 int sh_unix_lock (char * lockfile, char * flag); 3808 int sh_unix_unlock(char * lockfile, char * flag) 3809 { 3810 int error = 0; 3811 3812 SL_ENTER(_("sh_unix_unlock")); 3813 3814 if (sh.flag.isdaemon == S_FALSE && flag == NULL) 3815 SL_RETURN((0),_("sh_unix_unlock")); 3816 3817 /* --- Logfile is not locked to us. --- 3818 */ 3819 if (sh.flag.islocked == BAD && flag != NULL) 3820 SL_RETURN((-1),_("sh_unix_unlock")); 3821 3822 /* --- Check whether the directory is secure. --- 3823 */ 3824 if (0 != tf_trust_check (lockfile, SL_YESPRIV)) 3825 SL_RETURN((-1),_("sh_unix_unlock")); 3826 3827 /* --- Delete the lock file. --- 3828 */ 3829 error = retry_aud_unlink (FIL__, __LINE__, lockfile); 3830 3831 if (error == 0) 3832 { 3833 if (flag != NULL) 3834 sh.flag.islocked = BAD; /* not locked anymore */ 3835 } 3836 else if (flag != NULL) 3837 { 3838 char errbuf[SH_ERRBUF_SIZE]; 3839 error = errno; 3840 sh_error_handle ((-1), FIL__, __LINE__, error, MSG_E_UNLNK, 3841 sh_error_message(error, errbuf, sizeof(errbuf)), 3842 lockfile); 3843 SL_RETURN((-1),_("sh_unix_unlock")); 3844 } 3845 SL_RETURN((0),_("sh_unix_unlock")); 3846 } 3847 3848 int sh_unix_lock (char * lockfile, char * flag) 3849 { 3850 int filed; 3851 int errnum; 3852 char myPid[64]; 3853 SL_TICKET fd; 3854 extern int get_the_fd (SL_TICKET ticket); 3855 3856 SL_ENTER(_("sh_unix_lock")); 3857 3858 sprintf (myPid, "%ld\n", (long) sh.pid); /* known to fit */ 3859 3860 fd = sl_open_safe_rdwr (lockfile, SL_YESPRIV); /* fails if file exists */ 3861 3862 if (!SL_ISERROR(fd)) 3863 { 3864 errnum = sl_write (fd, myPid, sl_strlen(myPid)); 3865 filed = get_the_fd(fd); 3866 fchmod (filed, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH); 3867 sl_close (fd); 3868 3869 if (!SL_ISERROR(errnum)) 3870 { 3871 if (flag != NULL) 3872 sh.flag.islocked = GOOD; 3873 SL_RETURN((0),_("sh_unix_lock")); 3874 } 3875 } 3876 3877 TPT((0, FIL__, __LINE__, _("msg=<open pid file failed>\n"))); 3878 if (flag != NULL) 3879 sh.flag.islocked = BAD; 3880 SL_RETURN((-1),_("sh_unix_lock")); 3881 3882 /* notreached */ 3883 } 3884 3774 3885 3775 3886 /* check whether file is locked … … 3964 4075 } 3965 4076 3966 int sh_unix_unlock(char * lockfile, char * flag)3967 {3968 int error = 0;3969 3970 SL_ENTER(_("sh_unix_unlock"));3971 3972 /* --- Logfile is not locked to us. ---3973 */3974 if (sh.flag.islocked == BAD && flag != NULL)3975 SL_RETURN((-1),_("sh_unix_unlock"));3976 3977 /* --- Check whether the directory is secure. ---3978 */3979 if (0 != tf_trust_check (lockfile, SL_YESPRIV))3980 SL_RETURN((-1),_("sh_unix_unlock"));3981 3982 /* --- Delete the lock file. ---3983 */3984 error = retry_aud_unlink (FIL__, __LINE__, lockfile);3985 3986 if (error == 0)3987 {3988 if (flag != NULL)3989 sh.flag.islocked = BAD; /* not locked anymore */3990 }3991 else if (flag != NULL)3992 {3993 char errbuf[SH_ERRBUF_SIZE];3994 error = errno;3995 sh_error_handle ((-1), FIL__, __LINE__, error, MSG_E_UNLNK,3996 sh_error_message(error, errbuf, sizeof(errbuf)),3997 lockfile);3998 SL_RETURN((-1),_("sh_unix_unlock"));3999 }4000 SL_RETURN((0),_("sh_unix_unlock"));4001 }4002 4003 4077 /* rm lock for filename 4004 4078 */ … … 4029 4103 { 4030 4104 return sh_unix_unlock(sh.srvlog.alt, NULL); 4031 }4032 4033 int sh_unix_lock (char * lockfile, char * flag)4034 {4035 int filed;4036 int errnum;4037 char myPid[64];4038 SL_TICKET fd;4039 extern int get_the_fd (SL_TICKET ticket);4040 4041 SL_ENTER(_("sh_unix_lock"));4042 4043 sprintf (myPid, "%ld\n", (long) sh.pid); /* known to fit */4044 4045 fd = sl_open_safe_rdwr (lockfile, SL_YESPRIV); /* fails if file exists */4046 4047 if (!SL_ISERROR(fd))4048 {4049 errnum = sl_write (fd, myPid, sl_strlen(myPid));4050 filed = get_the_fd(fd);4051 fchmod (filed, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);4052 sl_close (fd);4053 4054 if (!SL_ISERROR(errnum))4055 {4056 if (flag != NULL)4057 sh.flag.islocked = GOOD;4058 SL_RETURN((0),_("sh_unix_lock"));4059 }4060 }4061 4062 TPT((0, FIL__, __LINE__, _("msg=<open pid file failed>\n")));4063 if (flag != NULL)4064 sh.flag.islocked = BAD;4065 SL_RETURN((-1),_("sh_unix_lock"));4066 4067 /* notreached */4068 4105 } 4069 4106 -
trunk/src/slib.c
r167 r169 108 108 int sl_trace_use (const char * dummy) 109 109 { 110 if (dummy) 111 slib_do_trace = 1; 112 else 113 slib_do_trace = 1; 110 (void) dummy; 111 slib_do_trace = 1; 114 112 return 0; 115 113 } … … 156 154 fprintf(trace_fp, "[%2d] %s \t - File %c%s%c at line %d\n", 157 155 trace_level, str, 0x22, file, 0x22, line); 156 fflush(trace_fp); 158 157 } 159 158 else … … 191 190 fprintf(trace_fp, _("[%2d] %s \t - File %c%s%c at line %d\n"), 192 191 trace_level, str, 0x22, file, 0x22, line); 192 fflush(trace_fp); 193 193 } 194 194 else … … 1007 1007 } 1008 1008 1009 #include <ctype.h> 1010 int sl_strcasecmp(const char * one, const char * two) 1011 { 1012 #ifdef SL_FAIL_ON_ERROR 1013 SL_REQUIRE (one != NULL, _("one != NULL")); 1014 SL_REQUIRE (two != NULL, _("two != NULL")); 1015 #endif 1016 1017 if (one && two) 1018 { 1019 do { 1020 if (*one && *two) 1021 { 1022 if (tolower(*one) == tolower(*two)) 1023 { 1024 ++one; ++two; 1025 } 1026 else if (tolower(*one) < tolower(*two)) 1027 return -1; 1028 else 1029 return 1; 1030 } 1031 else if (*one == '\0' && *two == '\0') 1032 return 0; 1033 else if (*one == '\0') 1034 return -1; 1035 else 1036 return 1; 1037 } while (1 == 1); 1038 } 1039 else if (one == NULL && two != NULL) 1040 return -1; 1041 else if (one != NULL && two == NULL) 1042 return 1; 1043 else 1044 return -7; /* default to not equal */ 1045 } 1009 1046 1010 1047 int sl_strcmp(const char * a, const char * b) … … 1022 1059 return (1); 1023 1060 else 1024 return (-7); /* arbitrary*/1061 return (-7); /* default to not equal */ 1025 1062 } 1026 1063 … … 1040 1077 return (1); 1041 1078 else 1042 return (-7); /* arbitrary*/1079 return (-7); /* default to not equal */ 1043 1080 } 1044 1081 … … 2232 2269 if (is_nonblocking == SL_FALSE) 2233 2270 retry_fcntl(FIL__, __LINE__, fd, F_SETFL, sflags); 2271 TPT(( 0, FIL__, __LINE__, _("msg=<read error>"))); 2234 2272 return (SL_EREAD); 2235 2273 } … … 2247 2285 if (is_nonblocking == SL_FALSE) 2248 2286 retry_fcntl(FIL__, __LINE__, fd, F_SETFL, sflags); 2287 TPT(( 0, FIL__, __LINE__, _("msg=<timeout>"))); 2249 2288 return (SL_TIMEOUT); 2250 2289 } … … 2253 2292 if (is_nonblocking == SL_FALSE) 2254 2293 retry_fcntl(FIL__, __LINE__, fd, F_SETFL, sflags); 2294 TPT(( 0, FIL__, __LINE__, _("msg=<timeout>"))); 2255 2295 return (SL_EREAD); 2256 2296 } … … 2260 2300 if (is_nonblocking == SL_FALSE) 2261 2301 retry_fcntl(FIL__, __LINE__, fd, F_SETFL, sflags); 2302 TPT(( 0, FIL__, __LINE__, _("msg=<terminated>"))); 2262 2303 return (SL_EREAD); 2263 2304 } … … 2270 2311 if (is_nonblocking == SL_FALSE) 2271 2312 retry_fcntl(FIL__, __LINE__, fd, F_SETFL, sflags); 2313 TPT(( 0, FIL__, __LINE__, _("msg=<timeout>"))); 2272 2314 return (SL_TIMEOUT); 2273 2315 } … … 2282 2324 int timeout, int is_nonblocking) 2283 2325 { 2284 int fd ;2326 int fd, retval; 2285 2327 2328 SL_ENTER(_("sl_read_timeout")); 2329 2286 2330 if (buf_in == NULL || SL_ISERROR(fd = get_the_fd(ticket))) 2287 2331 { … … 2289 2333 { 2290 2334 TPT(( 0, FIL__, __LINE__, _("msg=<null buffer>"))); 2291 return (SL_ENULL);2335 SL_IRETURN((SL_ENULL), _("sl_read_timeout")); 2292 2336 } 2293 2337 if (SL_ISERROR(fd = get_the_fd(ticket))) 2294 2338 { 2295 2339 TPT(( 0, FIL__, __LINE__, _("msg=<ticket error> errno=<%d>"), fd)); 2296 return (fd);2340 SL_IRETURN((fd), _("sl_read_timeout")); 2297 2341 } 2298 2342 } 2299 2343 2300 return sl_read_timeout_fd (fd, buf_in, count, timeout, is_nonblocking); 2344 retval = sl_read_timeout_fd (fd, buf_in, count, timeout, is_nonblocking); 2345 SL_IRETURN((retval), _("sl_read_timeout")); 2301 2346 } 2302 2347 … … 2310 2355 char * buf; 2311 2356 2357 SL_ENTER(_("sl_read")); 2358 2312 2359 if (count < 1) 2313 2360 { 2314 2361 TPT(( 0, FIL__, __LINE__, _("msg=<range error>"))); 2315 return(SL_ERANGE);2362 SL_IRETURN((SL_ERANGE), _("sl_read")); 2316 2363 } 2317 2364 if (buf_in == NULL) 2318 2365 { 2319 2366 TPT(( 0, FIL__, __LINE__, _("msg=<null buffer>"))); 2320 return (SL_ENULL);2367 SL_IRETURN((SL_ENULL), _("sl_read")); 2321 2368 } 2322 2369 … … 2324 2371 { 2325 2372 TPT(( 0, FIL__, __LINE__, _("msg=<ticket error> errno=<%d>"), fd)); 2326 return (fd);2373 SL_IRETURN((fd), _("sl_read")); 2327 2374 } 2328 2375 … … 2345 2392 { 2346 2393 TPT(( 0, FIL__, __LINE__, _("msg=<read error> errno=<%d>\n"), errno)); 2347 return (SL_EREAD);2348 } 2349 return (bytes);2394 SL_IRETURN((SL_EREAD), _("sl_read")); 2395 } 2396 SL_IRETURN((bytes), _("sl_read")); 2350 2397 } 2351 2398 … … 2357 2404 char * buf; 2358 2405 2406 SL_ENTER(_("sl_read_fast")); 2407 2359 2408 if (count < 1) 2360 2409 { 2361 2410 TPT(( 0, FIL__, __LINE__, _("msg=<range error>"))); 2362 return(SL_ERANGE);2411 SL_IRETURN((SL_ERANGE), _("sl_read_fast")); 2363 2412 } 2364 2413 if (buf_in == NULL) 2365 2414 { 2366 2415 TPT(( 0, FIL__, __LINE__, _("msg=<null buffer>"))); 2367 return (SL_ENULL);2416 SL_IRETURN((SL_ENULL), _("sl_read_fast")); 2368 2417 } 2369 2418 … … 2371 2420 { 2372 2421 TPT(( 0, FIL__, __LINE__, _("msg=<ticket error> errno=<%d>"), fd)); 2373 return (fd);2422 SL_IRETURN((fd), _("sl_read_fast")); 2374 2423 } 2375 2424 … … 2381 2430 if (byteread >= 0) 2382 2431 { 2383 return (byteread);2432 SL_IRETURN((byteread), _("sl_read_fast")); 2384 2433 } 2385 2434 } while ( byteread == -1 && (errno == EINTR || errno == EAGAIN)); … … 2389 2438 { 2390 2439 TPT(( 0, FIL__, __LINE__, _("msg=<read error> errno=<%d>\n"), errno)); 2391 return (SL_EREAD);2392 } 2393 return (0);2440 SL_IRETURN((SL_EREAD), _("sl_read_fast")); 2441 } 2442 SL_IRETURN((0), _("sl_read_fast")); 2394 2443 } 2395 2444
Note:
See TracChangeset
for help on using the changeset viewer.