Browse code

libclamav/dlp.c: improve detection of credit card numbers (bb#941)

git-svn: trunk@3909

Tomasz Kojm authored on 2008/07/04 21:49:59
Showing 2 changed files
... ...
@@ -1,3 +1,7 @@
1
+Fri Jul  4 14:21:12 CEST 2008 (tk)
2
+----------------------------------
3
+  * libclamav/dlp.c: improve detection of credit card numbers (bb#941)
4
+
1 5
 Thu Jul  3 16:02:03 EEST 2008 (edwin)
2 6
 -------------------------------------
3 7
   * libclamav/scanners.c: add missing check for file open failure (bb #1083).
... ...
@@ -119,6 +119,8 @@ int dlp_is_valid_cc(const unsigned char *buffer, int length)
119 119
     int sum = 0;
120 120
     int i = 0;
121 121
     int val = 0;
122
+    int digits = 0;
123
+    char prefix[4];
122 124
     
123 125
     if(buffer == NULL || length < 13)
124 126
         return 0;
... ...
@@ -127,17 +129,21 @@ int dlp_is_valid_cc(const unsigned char *buffer, int length)
127 127
      * credit cards
128 128
      * reference => http://www.beachnet.com/~hstiles/cardtype.html
129 129
      */
130
-    if(buffer[0] > '6')
130
+    if(buffer[0] > '6' || buffer[0] == 0)
131 131
         return 0;
132 132
         
133
-    if(length > 16)
134
-        length = 16;
133
+    if(length > 19)
134
+        length = 19;
135 135
 
136 136
     for(i = length - 1; i > -1; i--)
137 137
     {
138 138
         if(isdigit(buffer[i]) == 0)
139 139
             continue;
140
-        
140
+
141
+	if(digits < 4)
142
+	    prefix[digits] = buffer[i];
143
+
144
+	digits++;
141 145
         val = buffer[i] - '0';
142 146
         
143 147
         if(even)
... ...
@@ -148,8 +154,62 @@ int dlp_is_valid_cc(const unsigned char *buffer, int length)
148 148
         even = !even;
149 149
         sum += val;
150 150
     }
151
-    
152
-    return (sum % 10 == 0);
151
+
152
+    if((sum % 10 != 0) || (digits < 13))
153
+	return 0;
154
+
155
+    if(digits == 13) /* VISA */
156
+    {
157
+	if(prefix[0] == '4')
158
+	    return 1;
159
+    }
160
+    else if(digits == 14) /* Diners Club */
161
+    {
162
+	if(prefix[0] == '3' && (prefix[1] == '6' || prefix[1] == '8'))
163
+	{
164
+	    return 1;
165
+	}
166
+	else if(prefix[0] == '3' && prefix[1] == '0')
167
+	{
168
+	    val = prefix[2] - '0';
169
+	    if(val >= 0 && val <= 5)
170
+		return 1;
171
+	}
172
+    }
173
+    else if(digits == 15)
174
+    {
175
+	if(prefix[0] == '3' && (prefix[1] == '4' || prefix[1] == '7')) /*AMEX*/
176
+	{
177
+	    return 1;
178
+	}
179
+	else if(!strncmp(prefix, "2131", 4) || !strncmp(prefix, "1800", 4))
180
+	{ /* JCB  */
181
+	    return 1;
182
+	}
183
+    }
184
+    else if(digits == 16)
185
+    {
186
+	if(prefix[0] == '3') /* JCB */
187
+	{
188
+	    return 1;
189
+	}
190
+	else if(prefix[0] == '4') /* VISA */
191
+	{
192
+	    return 1;
193
+	}
194
+	else if(prefix[0] == '5') /* MASTERCARD */
195
+	{
196
+	    val = prefix[1] - '0';
197
+	    if(val >= 1 && val <= 5)
198
+		return 1;
199
+	}
200
+	else if(!strncmp(prefix, "6011", 4)) /* Discover */
201
+	{
202
+	    return 1;
203
+	} 
204
+    }
205
+
206
+    return 0;
153 207
 }
154 208
 
155 209
 static int contains_cc(const unsigned char *buffer, int length, int detmode)