- if ((p = Ustrstr(vname, "FOUND"))!=NULL) {
- *p=0;
- for (--p;p>vname && *p<=32;p--) *p=0;
- for (;*vname==32;vname++);
- Ustrcpy(malware_name_buffer,vname);
- malware_name = malware_name_buffer;
- DEBUG(D_acl) debug_printf("Malware found, name \"%s\"\n", malware_name);
- }
- else {
- if (Ustrstr(vname, "ERROR")!=NULL) {
- /* ClamAV reports ERROR
- Find line start */
- for (;*vname!='\n' && vname>av_buffer; vname--);
- if (*vname=='\n') vname++;
-
- log_write(0, LOG_MAIN|LOG_PANIC,
- "malware acl condition: clamd: ClamAV returned %s",vname);
- return DEFER;
- }
- else {
- /* Everything should be OK */
- malware_name = NULL;
- DEBUG(D_acl) debug_printf("Malware not found\n");
- }
+
+ /* It would be bad to encounter a virus with "FOUND" in part of the name,
+ but we should at least be resistant to it. */
+ p = Ustrrchr(vname, ' ');
+ if (p)
+ result_tag = p + 1;
+ else
+ result_tag = vname;
+
+ if (Ustrcmp(result_tag, "FOUND") == 0) {
+ /* p should still be the whitespace before the result_tag */
+ while (isspace(*p)) --p;
+ *++p = '\0';
+ /* Strip off the extended information too, which will be in parens
+ after the virus name, with no intervening whitespace. */
+ if (*--p == ')') {
+ /* "(hash:size)", so previous '(' will do; if not found, we have
+ a curious virus name, but not an error. */
+ p = Ustrrchr(vname, '(');
+ if (p)
+ *p = '\0';
+ }
+ Ustrncpy(malware_name_buffer, vname, sizeof(malware_name_buffer)-1);
+ malware_name = malware_name_buffer;
+ DEBUG(D_acl) debug_printf("Malware found, name \"%s\"\n", malware_name);
+
+ } else if (Ustrcmp(result_tag, "ERROR") == 0) {
+ log_write(0, LOG_MAIN|LOG_PANIC,
+ "malware acl condition: clamd: ClamAV returned: %s",
+ av_buffer);
+ return DEFER;
+
+ } else if (Ustrcmp(result_tag, "OK") == 0) {
+ /* Everything should be OK */
+ malware_name = NULL;
+ DEBUG(D_acl) debug_printf("Malware not found\n");
+
+ } else {
+ log_write(0, LOG_MAIN|LOG_PANIC,
+ "malware acl condition: clamd: unparseable response from ClamAV: {%s}",
+ av_buffer);
+ return DEFER;