diff options
Diffstat (limited to 'src/util/payto.c')
-rw-r--r-- | src/util/payto.c | 302 |
1 files changed, 1 insertions, 301 deletions
diff --git a/src/util/payto.c b/src/util/payto.c index 9a04f4c3c..58f1bf635 100644 --- a/src/util/payto.c +++ b/src/util/payto.c | |||
@@ -147,306 +147,6 @@ TALER_xtalerbank_account_from_payto (const char *payto) | |||
147 | } | 147 | } |
148 | 148 | ||
149 | 149 | ||
150 | /* Country table taken from GNU gettext */ | ||
151 | |||
152 | /** | ||
153 | * Entry in the country table. | ||
154 | */ | ||
155 | struct CountryTableEntry | ||
156 | { | ||
157 | /** | ||
158 | * 2-Character international country code. | ||
159 | */ | ||
160 | const char *code; | ||
161 | |||
162 | /** | ||
163 | * Long English name of the country. | ||
164 | */ | ||
165 | const char *english; | ||
166 | }; | ||
167 | |||
168 | |||
169 | /* Keep the following table in sync with gettext. | ||
170 | WARNING: the entries should stay sorted according to the code */ | ||
171 | /** | ||
172 | * List of country codes. | ||
173 | */ | ||
174 | static const struct CountryTableEntry country_table[] = { | ||
175 | { "AE", "U.A.E." }, | ||
176 | { "AF", "Afghanistan" }, | ||
177 | { "AL", "Albania" }, | ||
178 | { "AM", "Armenia" }, | ||
179 | { "AN", "Netherlands Antilles" }, | ||
180 | { "AR", "Argentina" }, | ||
181 | { "AT", "Austria" }, | ||
182 | { "AU", "Australia" }, | ||
183 | { "AZ", "Azerbaijan" }, | ||
184 | { "BA", "Bosnia and Herzegovina" }, | ||
185 | { "BD", "Bangladesh" }, | ||
186 | { "BE", "Belgium" }, | ||
187 | { "BG", "Bulgaria" }, | ||
188 | { "BH", "Bahrain" }, | ||
189 | { "BN", "Brunei Darussalam" }, | ||
190 | { "BO", "Bolivia" }, | ||
191 | { "BR", "Brazil" }, | ||
192 | { "BT", "Bhutan" }, | ||
193 | { "BY", "Belarus" }, | ||
194 | { "BZ", "Belize" }, | ||
195 | { "CA", "Canada" }, | ||
196 | { "CG", "Congo" }, | ||
197 | { "CH", "Switzerland" }, | ||
198 | { "CI", "Cote d'Ivoire" }, | ||
199 | { "CL", "Chile" }, | ||
200 | { "CM", "Cameroon" }, | ||
201 | { "CN", "People's Republic of China" }, | ||
202 | { "CO", "Colombia" }, | ||
203 | { "CR", "Costa Rica" }, | ||
204 | { "CS", "Serbia and Montenegro" }, | ||
205 | { "CZ", "Czech Republic" }, | ||
206 | { "DE", "Germany" }, | ||
207 | { "DK", "Denmark" }, | ||
208 | { "DO", "Dominican Republic" }, | ||
209 | { "DZ", "Algeria" }, | ||
210 | { "EC", "Ecuador" }, | ||
211 | { "EE", "Estonia" }, | ||
212 | { "EG", "Egypt" }, | ||
213 | { "ER", "Eritrea" }, | ||
214 | { "ES", "Spain" }, | ||
215 | { "ET", "Ethiopia" }, | ||
216 | { "FI", "Finland" }, | ||
217 | { "FO", "Faroe Islands" }, | ||
218 | { "FR", "France" }, | ||
219 | { "GB", "United Kingdom" }, | ||
220 | { "GD", "Caribbean" }, | ||
221 | { "GE", "Georgia" }, | ||
222 | { "GL", "Greenland" }, | ||
223 | { "GR", "Greece" }, | ||
224 | { "GT", "Guatemala" }, | ||
225 | { "HK", "Hong Kong" }, | ||
226 | { "HK", "Hong Kong S.A.R." }, | ||
227 | { "HN", "Honduras" }, | ||
228 | { "HR", "Croatia" }, | ||
229 | { "HT", "Haiti" }, | ||
230 | { "HU", "Hungary" }, | ||
231 | { "ID", "Indonesia" }, | ||
232 | { "IE", "Ireland" }, | ||
233 | { "IL", "Israel" }, | ||
234 | { "IN", "India" }, | ||
235 | { "IQ", "Iraq" }, | ||
236 | { "IR", "Iran" }, | ||
237 | { "IS", "Iceland" }, | ||
238 | { "IT", "Italy" }, | ||
239 | { "JM", "Jamaica" }, | ||
240 | { "JO", "Jordan" }, | ||
241 | { "JP", "Japan" }, | ||
242 | { "KE", "Kenya" }, | ||
243 | { "KG", "Kyrgyzstan" }, | ||
244 | { "KH", "Cambodia" }, | ||
245 | { "KR", "South Korea" }, | ||
246 | { "KW", "Kuwait" }, | ||
247 | { "KZ", "Kazakhstan" }, | ||
248 | { "LA", "Laos" }, | ||
249 | { "LB", "Lebanon" }, | ||
250 | { "LI", "Liechtenstein" }, | ||
251 | { "LK", "Sri Lanka" }, | ||
252 | { "LT", "Lithuania" }, | ||
253 | { "LU", "Luxembourg" }, | ||
254 | { "LV", "Latvia" }, | ||
255 | { "LY", "Libya" }, | ||
256 | { "MA", "Morocco" }, | ||
257 | { "MC", "Principality of Monaco" }, | ||
258 | { "MD", "Moldava" }, | ||
259 | { "MD", "Moldova" }, | ||
260 | { "ME", "Montenegro" }, | ||
261 | { "MK", "Former Yugoslav Republic of Macedonia" }, | ||
262 | { "ML", "Mali" }, | ||
263 | { "MM", "Myanmar" }, | ||
264 | { "MN", "Mongolia" }, | ||
265 | { "MO", "Macau S.A.R." }, | ||
266 | { "MT", "Malta" }, | ||
267 | { "MV", "Maldives" }, | ||
268 | { "MX", "Mexico" }, | ||
269 | { "MY", "Malaysia" }, | ||
270 | { "NG", "Nigeria" }, | ||
271 | { "NI", "Nicaragua" }, | ||
272 | { "NL", "Netherlands" }, | ||
273 | { "NO", "Norway" }, | ||
274 | { "NP", "Nepal" }, | ||
275 | { "NZ", "New Zealand" }, | ||
276 | { "OM", "Oman" }, | ||
277 | { "PA", "Panama" }, | ||
278 | { "PE", "Peru" }, | ||
279 | { "PH", "Philippines" }, | ||
280 | { "PK", "Islamic Republic of Pakistan" }, | ||
281 | { "PL", "Poland" }, | ||
282 | { "PR", "Puerto Rico" }, | ||
283 | { "PT", "Portugal" }, | ||
284 | { "PY", "Paraguay" }, | ||
285 | { "QA", "Qatar" }, | ||
286 | { "RE", "Reunion" }, | ||
287 | { "RO", "Romania" }, | ||
288 | { "RS", "Serbia" }, | ||
289 | { "RU", "Russia" }, | ||
290 | { "RW", "Rwanda" }, | ||
291 | { "SA", "Saudi Arabia" }, | ||
292 | { "SE", "Sweden" }, | ||
293 | { "SG", "Singapore" }, | ||
294 | { "SI", "Slovenia" }, | ||
295 | { "SK", "Slovak" }, | ||
296 | { "SN", "Senegal" }, | ||
297 | { "SO", "Somalia" }, | ||
298 | { "SR", "Suriname" }, | ||
299 | { "SV", "El Salvador" }, | ||
300 | { "SY", "Syria" }, | ||
301 | { "TH", "Thailand" }, | ||
302 | { "TJ", "Tajikistan" }, | ||
303 | { "TM", "Turkmenistan" }, | ||
304 | { "TN", "Tunisia" }, | ||
305 | { "TR", "Turkey" }, | ||
306 | { "TT", "Trinidad and Tobago" }, | ||
307 | { "TW", "Taiwan" }, | ||
308 | { "TZ", "Tanzania" }, | ||
309 | { "UA", "Ukraine" }, | ||
310 | { "US", "United States" }, | ||
311 | { "UY", "Uruguay" }, | ||
312 | { "VA", "Vatican" }, | ||
313 | { "VE", "Venezuela" }, | ||
314 | { "VN", "Viet Nam" }, | ||
315 | { "YE", "Yemen" }, | ||
316 | { "ZA", "South Africa" }, | ||
317 | { "ZW", "Zimbabwe" } | ||
318 | }; | ||
319 | |||
320 | |||
321 | /** | ||
322 | * Country code comparator function, for binary search with bsearch(). | ||
323 | * | ||
324 | * @param ptr1 pointer to a `struct table_entry` | ||
325 | * @param ptr2 pointer to a `struct table_entry` | ||
326 | * @return result of memcmp()'ing the 2-digit country codes of the entries | ||
327 | */ | ||
328 | static int | ||
329 | cmp_country_code (const void *ptr1, | ||
330 | const void *ptr2) | ||
331 | { | ||
332 | const struct CountryTableEntry *cc1 = ptr1; | ||
333 | const struct CountryTableEntry *cc2 = ptr2; | ||
334 | |||
335 | return memcmp (cc1->code, | ||
336 | cc2->code, | ||
337 | 2); | ||
338 | } | ||
339 | |||
340 | |||
341 | /** | ||
342 | * Validates given IBAN according to the European Banking Standards. See: | ||
343 | * http://www.europeanpaymentscouncil.eu/documents/ECBS%20IBAN%20standard%20EBS204_V3.2.pdf | ||
344 | * | ||
345 | * @param iban the IBAN number to validate | ||
346 | * @return NULL if correctly formatted; error message if not | ||
347 | */ | ||
348 | static char * | ||
349 | validate_iban (const char *iban) | ||
350 | { | ||
351 | char cc[2]; | ||
352 | char ibancpy[35]; | ||
353 | struct CountryTableEntry cc_entry; | ||
354 | unsigned int len; | ||
355 | char *nbuf; | ||
356 | unsigned long long dividend; | ||
357 | unsigned long long remainder; | ||
358 | unsigned int i; | ||
359 | unsigned int j; | ||
360 | |||
361 | len = strlen (iban); | ||
362 | if (len < 4) | ||
363 | return GNUNET_strdup ("IBAN number too short to be valid"); | ||
364 | if (len > 34) | ||
365 | return GNUNET_strdup ("IBAN number too long to be valid"); | ||
366 | memcpy (cc, iban, 2); | ||
367 | memcpy (ibancpy, iban + 4, len - 4); | ||
368 | memcpy (ibancpy + len - 4, iban, 4); | ||
369 | ibancpy[len] = '\0'; | ||
370 | cc_entry.code = cc; | ||
371 | cc_entry.english = NULL; | ||
372 | if (NULL == | ||
373 | bsearch (&cc_entry, | ||
374 | country_table, | ||
375 | sizeof (country_table) / sizeof (struct CountryTableEntry), | ||
376 | sizeof (struct CountryTableEntry), | ||
377 | &cmp_country_code)) | ||
378 | { | ||
379 | char *msg; | ||
380 | |||
381 | GNUNET_asprintf (&msg, | ||
382 | "Country code `%c%c' not supported\n", | ||
383 | cc[0], | ||
384 | cc[1]); | ||
385 | return msg; | ||
386 | } | ||
387 | nbuf = GNUNET_malloc ((len * 2) + 1); | ||
388 | for (i = 0, j = 0; i < len; i++) | ||
389 | { | ||
390 | if (isalpha ((unsigned char) ibancpy[i])) | ||
391 | { | ||
392 | if (2 != snprintf (&nbuf[j], | ||
393 | 3, | ||
394 | "%2u", | ||
395 | (ibancpy[i] - 'A' + 10))) | ||
396 | { | ||
397 | GNUNET_break (0); | ||
398 | return GNUNET_strdup ("internal invariant violation"); | ||
399 | } | ||
400 | j += 2; | ||
401 | continue; | ||
402 | } | ||
403 | nbuf[j] = ibancpy[i]; | ||
404 | j++; | ||
405 | } | ||
406 | for (j = 0; '\0' != nbuf[j]; j++) | ||
407 | { | ||
408 | if (! isdigit ( (unsigned char) nbuf[j])) | ||
409 | { | ||
410 | char *msg; | ||
411 | |||
412 | GNUNET_asprintf (&msg, | ||
413 | "digit expected at `%s'", | ||
414 | &nbuf[j]); | ||
415 | GNUNET_free (nbuf); | ||
416 | return msg; | ||
417 | } | ||
418 | } | ||
419 | GNUNET_assert (sizeof(dividend) >= 8); | ||
420 | remainder = 0; | ||
421 | for (unsigned int i = 0; i<j; i += 16) | ||
422 | { | ||
423 | int nread; | ||
424 | |||
425 | if (1 != | ||
426 | sscanf (&nbuf[i], | ||
427 | "%16llu %n", | ||
428 | ÷nd, | ||
429 | &nread)) | ||
430 | { | ||
431 | char *msg; | ||
432 | |||
433 | GNUNET_asprintf (&msg, | ||
434 | "wrong input for checksum calculation at `%s'", | ||
435 | &nbuf[i]); | ||
436 | GNUNET_free (nbuf); | ||
437 | return msg; | ||
438 | } | ||
439 | if (0 != remainder) | ||
440 | dividend += remainder * (pow (10, nread)); | ||
441 | remainder = dividend % 97; | ||
442 | } | ||
443 | GNUNET_free (nbuf); | ||
444 | if (1 != remainder) | ||
445 | return GNUNET_strdup ("IBAN checksum is wrong"); | ||
446 | return NULL; | ||
447 | } | ||
448 | |||
449 | |||
450 | /** | 150 | /** |
451 | * Validate payto://iban/ account URL (only account information, | 151 | * Validate payto://iban/ account URL (only account information, |
452 | * wire subject and amount are ignored). | 152 | * wire subject and amount are ignored). |
@@ -483,7 +183,7 @@ validate_payto_iban (const char *account_url) | |||
483 | result = GNUNET_strdup (iban); | 183 | result = GNUNET_strdup (iban); |
484 | } | 184 | } |
485 | if (NULL != | 185 | if (NULL != |
486 | (err = validate_iban (result))) | 186 | (err = TALER_iban_validate (result))) |
487 | { | 187 | { |
488 | GNUNET_free (result); | 188 | GNUNET_free (result); |
489 | return err; | 189 | return err; |