• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

geographika / mapserver / 12180102655

05 Dec 2024 12:50PM UTC coverage: 40.361% (+0.08%) from 40.281%
12180102655

push

github

geographika
Add back all Python versions

58368 of 144616 relevant lines covered (40.36%)

25464.83 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

59.06
/src/mapcrypto.c
1
/******************************************************************************
2
 * $Id$
3
 *
4
 * Project:  MapServer
5
 * Purpose:  Encryption functions (see MS-RFC-18)
6
 * Author:   Daniel Morissette
7
 *
8
 ******************************************************************************
9
 * Copyright (c) 1996-2006 Regents of the University of Minnesota.
10
 *
11
 * Permission is hereby granted, free of charge, to any person obtaining a
12
 * copy of this software and associated documentation files (the "Software"),
13
 * to deal in the Software without restriction, including without limitation
14
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
15
 * and/or sell copies of the Software, and to permit persons to whom the
16
 * Software is furnished to do so, subject to the following conditions:
17
 *
18
 * The above copyright notice and this permission notice shall be included in
19
 * all copies of this Software or works derived from this Software.
20
 *
21
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
22
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
24
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
27
 * DEALINGS IN THE SOFTWARE.
28
 ****************************************************************************/
29

30
#include <assert.h>
31
#include <ctype.h>  /* isxdigit() */
32
#include <stdlib.h> /* rand() */
33
#include <time.h>   /* time() */
34

35
#include "mapserver.h"
36

37
#include "cpl_conv.h"
38

39
/**********************************************************************
40
 * encipher() and decipher() from the Tiny Encryption Algorithm (TEA)
41
 * website at:
42
 *   http://www.simonshepherd.supanet.com/tea.htm
43
 *
44
 * TEA was developed and placed in the public domain by David Wheeler
45
 * and Roger Needham at the Computer Laboratory of Cambridge University.
46
 *
47
 * The source below came with the following public domain notice:
48
 *
49
 *   "Please feel free to use any of this code in your applications.
50
 *    The TEA algorithm (including new-variant TEA) has been placed
51
 *    in the public domain, as have my assembly language implementations."
52
 *
53
 * ... and the following usage notes:
54
 *
55
 * All the routines have the general form
56
 *
57
 *  void encipher(const unsigned long *const v,unsigned long *const w,
58
 *                const unsigned long * const k);
59
 *
60
 *  void decipher(const unsigned long *const v,unsigned long *const w,
61
 *                const unsigned long * const k);
62
 *
63
 * TEA takes 64 bits of data in v[0] and v[1], and 128 bits of key in
64
 * k[0] - k[3]. The result is returned in w[0] and w[1]. Returning the
65
 * result separately makes implementation of cipher modes other than
66
 * Electronic Code Book a little bit easier.
67
 *
68
 * TEA can be operated in any of the modes of DES.
69
 *
70
 * n is the number of iterations. 32 is ample, 16 is sufficient, as few
71
 * as eight should be OK for most applications, especially ones where
72
 * the data age quickly (real-time video, for example). The algorithm
73
 * achieves good dispersion after six iterations. The iteration count
74
 * can be made variable if required.
75
 *
76
 * Note this algorithm is optimised for 32-bit CPUs with fast shift
77
 * capabilities. It can very easily be ported to assembly language
78
 * on most CPUs.
79
 *
80
 * delta is chosen to be the Golden ratio ((5/4)1/2 - 1/2 ~ 0.618034)
81
 * multiplied by 232. On entry to decipher(), sum is set to be delta * n.
82
 * Which way round you call the functions is arbitrary: DK(EK(P)) = EK(DK(P))
83
 * where EK and DK are encryption and decryption under key K respectively.
84
 *
85
 **********************************************************************/
86

87
static void encipher(const ms_uint32 *const v, ms_uint32 *const w,
×
88
                     const ms_uint32 *const k) {
89
  register ms_uint32 y = v[0], z = v[1], sum = 0, delta = 0x9E3779B9, n = 32;
×
90

91
  while (n-- > 0) {
×
92
    y += ((z << 4 ^ z >> 5) + z) ^ (sum + k[sum & 3]);
×
93
    sum += delta;
×
94
    z += ((y << 4 ^ y >> 5) + y) ^ (sum + k[sum >> 11 & 3]);
×
95
  }
96

97
  w[0] = y;
×
98
  w[1] = z;
×
99
}
×
100

101
static void decipher(const ms_uint32 *const v, ms_uint32 *const w,
9✔
102
                     const ms_uint32 *const k) {
103
  register ms_uint32 y = v[0], z = v[1], sum = 0xC6EF3720, delta = 0x9E3779B9,
9✔
104
                     n = 32;
105

106
  /* sum = delta<<5, in general sum = delta * n */
107

108
  while (n-- > 0) {
297✔
109
    z -= ((y << 4 ^ y >> 5) + y) ^ (sum + k[sum >> 11 & 3]);
288✔
110
    sum -= delta;
288✔
111
    y -= ((z << 4 ^ z >> 5) + z) ^ (sum + k[sum & 3]);
288✔
112
  }
113

114
  w[0] = y;
9✔
115
  w[1] = z;
9✔
116
}
9✔
117

118
/**********************************************************************
119
 *                          msHexEncode()
120
 *
121
 * Hex-encode numbytes from in[] and return the result in out[].
122
 *
123
 * out[] should be preallocated by the caller to be at least 2*numbytes+1
124
 * (+1 for the terminating '\0')
125
 **********************************************************************/
126
void msHexEncode(const unsigned char *in, char *out, int numbytes) {
×
127
  char *hex = "0123456789ABCDEF";
128

129
  while (numbytes-- > 0) {
×
130
    *out++ = hex[*in / 16];
×
131
    *out++ = hex[*in % 16];
×
132
    in++;
×
133
  }
134
  *out = '\0';
×
135
}
×
136

137
/**********************************************************************
138
 *                          msHexDecode()
139
 *
140
 * Hex-decode numchars from in[] and return the result in out[].
141
 *
142
 * If numchars > 0 then only up to this number of chars from in[] are
143
 * processed, otherwise the full in[] string up to the '\0' is processed.
144
 *
145
 * out[] should be preallocated by the caller to be large enough to hold
146
 * the resulting bytes.
147
 *
148
 * Returns the number of bytes written to out[] which may be different from
149
 * numchars/2 if an error or a '\0' is encountered.
150
 **********************************************************************/
151
int msHexDecode(const char *in, unsigned char *out, int numchars) {
19✔
152
  int numbytes_out = 0;
153

154
  /* Make sure numchars is even */
155
  numchars = (numchars / 2) * 2;
19✔
156

157
  if (numchars < 2)
19✔
158
    numchars = -1; /* Will result in this value being ignored in the loop*/
159

160
  while (*in != '\0' && *(in + 1) != '\0' && numchars != 0) {
107✔
161
    *out = 0x10 * (*in >= 'A' ? ((*in & 0xdf) - 'A') + 10 : (*in - '0'));
88✔
162
    in++;
163
    *out += (*in >= 'A' ? ((*in & 0xdf) - 'A') + 10 : (*in - '0'));
88✔
164
    in++;
88✔
165

166
    out++;
88✔
167
    numbytes_out++;
88✔
168

169
    numchars -= 2;
88✔
170
  }
171

172
  return numbytes_out;
19✔
173
}
174

175
/**********************************************************************
176
 *                       msGenerateEncryptionKey()
177
 *
178
 * Create a new encryption key.
179
 *
180
 * The output buffer should be at least MS_ENCRYPTION_KEY_SIZE bytes.
181
 **********************************************************************/
182

183
int msGenerateEncryptionKey(unsigned char *k) {
×
184
  int i;
185

186
  /* Use current time as seed for rand() */
187
  srand((unsigned int)time(NULL));
×
188

189
  for (i = 0; i < MS_ENCRYPTION_KEY_SIZE; i++) {
×
190
    /* coverity[dont_call] */
191
    k[i] = (unsigned char)rand();
×
192
  }
193

194
  return MS_SUCCESS;
×
195
}
196

197
/**********************************************************************
198
 *                       msReadEncryptionKeyFromFile()
199
 *
200
 * Read and decode hex-encoded encryption key from file and returns the
201
 * key in the 'unsigned char k[MS_ENCRYPTION_KEY_SIZE]' buffer that is
202
 * provided by the caller.
203
 *
204
 * Returns MS_SUCCESS/MS_FAILURE.
205
 **********************************************************************/
206

207
int msReadEncryptionKeyFromFile(const char *keyfile, unsigned char *k,
1✔
208
                                const char *pszRelToPath) {
209
  FILE *fp;
210
  char extended_path[MS_MAXPATHLEN];
211
  char szBuf[100];
212
  int numchars;
213

214
  /* Try to make the path relative */
215
  if (msBuildPath(extended_path, pszRelToPath, keyfile) == NULL)
1✔
216
    return MS_FAILURE;
217

218
  keyfile = extended_path;
219

220
  if ((fp = fopen(keyfile, "rt")) == NULL) {
1✔
221
    msSetError(MS_MISCERR, "Cannot open key file.",
×
222
               "msReadEncryptionKeyFromFile()");
223
    return MS_FAILURE;
×
224
  }
225

226
  numchars =
1✔
227
      fread(szBuf, sizeof(unsigned char), MS_ENCRYPTION_KEY_SIZE * 2, fp);
228
  fclose(fp);
1✔
229
  szBuf[MS_ENCRYPTION_KEY_SIZE * 2] = '\0';
1✔
230

231
  if (numchars != MS_ENCRYPTION_KEY_SIZE * 2) {
1✔
232
    msSetError(MS_MISCERR, "Invalid key file, got %d chars, expected %d.",
×
233
               "msReadEncryptionKeyFromFile()", numchars,
234
               MS_ENCRYPTION_KEY_SIZE * 2);
235
    return MS_FAILURE;
×
236
  }
237

238
  msHexDecode(szBuf, k, MS_ENCRYPTION_KEY_SIZE * 2);
1✔
239

240
  return MS_SUCCESS;
1✔
241
}
242

243
/**********************************************************************
244
 *                       msLoadEncryptionKey()
245
 *
246
 * Load and decode hex-encoded encryption key from file and returns the
247
 * key in the 'unsigned char k[MS_ENCRYPTION_KEY_SIZE]' buffer that is
248
 * provided by the caller.
249
 *
250
 * The first time that msLoadEncryptionKey() is called for a given mapObj
251
 * it will load the encryption key and cache it in mapObj->encryption_key.
252
 * If the key is already set in the mapObj then it does nothing and returns.
253
 *
254
 * The location of the encryption key can be specified in two ways,
255
 * either by setting the environment variable MS_ENCRYPTION_KEY or using
256
 * a CONFIG directive:
257
 *    CONFIG MS_ENCRYPTION_KEY "/path/to/mykey.txt"
258
 * Returns MS_SUCCESS/MS_FAILURE.
259
 **********************************************************************/
260

261
static int msLoadEncryptionKey(mapObj *map) {
6✔
262
  const char *keyfile;
263

264
  if (map == NULL) {
6✔
265
    msSetError(MS_MISCERR, "NULL MapObj.", "msLoadEncryptionKey()");
×
266
    return MS_FAILURE;
×
267
  }
268

269
  if (map->encryption_key_loaded)
6✔
270
    return MS_SUCCESS; /* Already loaded */
271

272
  keyfile = msGetConfigOption(map, "MS_ENCRYPTION_KEY");
1✔
273
  if (!keyfile)
1✔
274
    keyfile = CPLGetConfigOption("MS_ENCRYPTION_KEY", NULL);
×
275

276
  if (keyfile && msReadEncryptionKeyFromFile(keyfile, map->encryption_key,
2✔
277
                                             map->mappath) == MS_SUCCESS) {
1✔
278
    map->encryption_key_loaded = MS_TRUE;
1✔
279
  } else {
280
    msSetError(MS_MISCERR,
×
281
               "Failed reading encryption key. Make sure "
282
               "MS_ENCRYPTION_KEY is set and points to a valid key file.",
283
               "msLoadEncryptionKey()");
284
    return MS_FAILURE;
×
285
  }
286

287
  return MS_SUCCESS;
1✔
288
}
289

290
/**********************************************************************
291
 *                        msEncryptStringWithKey()
292
 *
293
 * Encrypts and hex-encodes the contents of string in[] and returns the
294
 * result in out[] which should have been pre-allocated by the caller
295
 * to be at least twice the size of in[] + 16+1 bytes (for padding + '\0').
296
 *
297
 **********************************************************************/
298

299
void msEncryptStringWithKey(const unsigned char *key, const char *in,
×
300
                            char *out) {
301
  ms_uint32 v[4], w[4];
302
  const ms_uint32 *k;
303
  int last_block = MS_FALSE;
304

305
  /* Casting the key this way is safe only as long as longs are 4 bytes
306
   * on this platform */
307
  assert(sizeof(ms_uint32) == 4);
308
  k = (const ms_uint32 *)key;
309

310
  while (!last_block) {
×
311
    int i, j;
312
    /* encipher() takes v[2] (64 bits) as input.
313
     * Copy bytes from in[] to the v[2] input array (pair of 4 bytes)
314
     * v[] is padded with zeros if string doesn't align with 8 bytes
315
     */
316
    v[0] = 0;
×
317
    v[1] = 0;
×
318
    for (i = 0; !last_block && i < 2; i++) {
×
319
      for (j = 0; j < 4; j++) {
×
320
        if (*in == '\0') {
×
321
          last_block = MS_TRUE;
322
          break;
323
        }
324

325
        v[i] |= *in << (j * 8);
×
326
        in++;
×
327
      }
328
    }
329

330
    if (*in == '\0')
×
331
      last_block = MS_TRUE;
332

333
    /* Do the actual encryption */
334
    encipher(v, w, k);
×
335

336
    /* Append hex-encoded bytes to output, 4 bytes at a time */
337
    msHexEncode((unsigned char *)w, out, 4);
×
338
    out += 8;
×
339
    msHexEncode((unsigned char *)(w + 1), out, 4);
×
340
    out += 8;
×
341
  }
342

343
  /* Make sure output is 0-terminated */
344
  *out = '\0';
×
345
}
×
346

347
/**********************************************************************
348
 *                        msDecryptStringWithKey()
349
 *
350
 * Hex-decodes and then decrypts the contents of string in[] and returns the
351
 * result in out[] which should have been pre-allocated by the caller
352
 * to be at least half the size of in[].
353
 *
354
 **********************************************************************/
355

356
void msDecryptStringWithKey(const unsigned char *key, const char *in,
6✔
357
                            char *out) {
358
  ms_uint32 v[4], w[4];
359
  const ms_uint32 *k;
360
  int last_block = MS_FALSE;
361

362
  /* Casting the key this way is safe only as long as longs are 4 bytes
363
   * on this platform */
364
  assert(sizeof(ms_uint32) == 4);
365
  k = (const ms_uint32 *)key;
366

367
  while (!last_block) {
15✔
368
    int i;
369
    /* decipher() takes v[2] (64 bits) as input.
370
     * Copy bytes from in[] to the v[2] input array (pair of 4 bytes)
371
     * v[] is padded with zeros if string doesn't align with 8 bytes
372
     */
373
    v[0] = 0;
9✔
374
    v[1] = 0;
9✔
375

376
    if (msHexDecode(in, (unsigned char *)v, 8) != 4)
9✔
377
      last_block = MS_TRUE;
378
    else {
379
      in += 8;
9✔
380
      if (msHexDecode(in, (unsigned char *)(v + 1), 8) != 4)
9✔
381
        last_block = MS_TRUE;
382
      else
383
        in += 8;
9✔
384
    }
385

386
    /* Do the actual decryption */
387
    decipher(v, w, k);
9✔
388

389
    /* Copy the results to out[] */
390
    for (i = 0; i < 2; i++) {
27✔
391
      *out++ = (w[i] & 0x000000ff);
18✔
392
      *out++ = (w[i] & 0x0000ff00) >> 8;
18✔
393
      *out++ = (w[i] & 0x00ff0000) >> 16;
18✔
394
      *out++ = (w[i] & 0xff000000) >> 24;
18✔
395
    }
396

397
    if (*in == '\0')
9✔
398
      last_block = MS_TRUE;
399
  }
400

401
  /* Make sure output is 0-terminated */
402
  *out = '\0';
6✔
403
}
6✔
404

405
/**********************************************************************
406
 *                        msDecryptStringTokens()
407
 *
408
 * Returns a newly allocated string (to be msFree'd by the caller) in
409
 * which all occurrences of encrypted strings delimited by {...} have
410
 * been decrypted.
411
 *
412
 **********************************************************************/
413

414
char *msDecryptStringTokens(mapObj *map, const char *in) {
2,027✔
415
  char *outbuf, *out;
416

417
  if (map == NULL) {
2,027✔
418
    msSetError(MS_MISCERR, "NULL MapObj.", "msLoadEncryptionKey()");
×
419
    return NULL;
×
420
  }
421

422
  /* Start with a copy of the string. Decryption can only result in
423
   * a string with the same or shorter length */
424
  if ((outbuf = (char *)malloc((strlen(in) + 1) * sizeof(char))) == NULL) {
2,027✔
425
    msSetError(MS_MEMERR, NULL, "msDecryptStringTokens()");
×
426
    return NULL;
×
427
  }
428
  out = outbuf;
429

430
  while (*in != '\0') {
96,156✔
431
    if (*in == '{') {
94,129✔
432
      /* Possibly beginning of a token, look for closing bracket
433
      ** and make sure all chars in between are valid hex encoding chars
434
      */
435
      const char *pszStart, *pszEnd;
436
      int valid_token = MS_FALSE;
437

438
      pszStart = in + 1;
6✔
439
      if ((pszEnd = strchr(pszStart, '}')) != NULL && pszEnd - pszStart > 1) {
6✔
440
        const char *pszTmp;
441
        valid_token = MS_TRUE;
442
        for (pszTmp = pszStart; pszTmp < pszEnd; pszTmp++) {
150✔
443
          if (!isxdigit(*pszTmp)) {
144✔
444
            valid_token = MS_FALSE;
445
            break;
446
          }
447
        }
448
      }
449

450
      if (valid_token) {
6✔
451
        /* Go ahead and decrypt the token */
452
        char *pszTmp;
453

454
        /* Make sure encryption key is loaded. We do this here instead
455
         * of at the beginning of the function to avoid loading the
456
         * key unless ready necessary. This is a very cheap call if
457
         * the key is already loaded
458
         */
459
        if (msLoadEncryptionKey(map) != MS_SUCCESS)
6✔
460
          return NULL;
461

462
        pszTmp = (char *)malloc((pszEnd - pszStart + 1) * sizeof(char));
6✔
463
        strlcpy(pszTmp, pszStart, (pszEnd - pszStart) + 1);
6✔
464

465
        msDecryptStringWithKey(map->encryption_key, pszTmp, out);
6✔
466

467
        out += strlen(out);
6✔
468
        in = pszEnd + 1;
6✔
469
        free(pszTmp);
6✔
470
      } else {
471
        /* Not a valid token, just copy the '{' and keep going */
472
        *out++ = *in++;
×
473
      }
474
    } else {
475
      /* Just copy any other chars */
476
      *out++ = *in++;
94,123✔
477
    }
478
  }
479
  *out = '\0';
2,027✔
480

481
  return outbuf;
2,027✔
482
}
483

484
#ifdef TEST_MAPCRYPTO
485

486
/* Test for mapcrypto.c functions. To run these tests, use the following
487
** Makefile directive:
488

489
test_mapcrypto: $(LIBMAP_STATIC) mapcrypto.c
490
  $(CC) $(CFLAGS) mapcrypto.c -DTEST_MAPCRYPTO $(EXE_LDFLAGS) -o test_mapcrypto
491

492
**
493
*/
494
int main(int argc, char *argv[]) {
495
  const unsigned char bytes_in[] = {0x12, 0x34, 0xff, 0x00, 0x44, 0x22};
496
  unsigned char bytes_out[8], encryption_key[MS_ENCRYPTION_KEY_SIZE * 2 + 1];
497
  char string_buf[256], string_buf2[256];
498
  int numbytes = 0;
499

500
  /*
501
  ** Test msHexEncode()
502
  */
503
  msHexEncode(bytes_in, string_buf, 6);
504
  printf("msHexEncode returned '%s'\n", string_buf);
505

506
  /*
507
  ** Test msHexDecode()
508
  */
509
  memset(bytes_out, 0, 8);
510
  numbytes = msHexDecode(string_buf, bytes_out, -1);
511
  printf(
512
      "msHexDecode(%s, -1) = %d, bytes_out = %x, %x, %x, %x, %x, %x, %x, %x\n",
513
      string_buf, numbytes, bytes_out[0], bytes_out[1], bytes_out[2],
514
      bytes_out[3], bytes_out[4], bytes_out[5], bytes_out[6], bytes_out[7]);
515

516
  memset(bytes_out, 0, 8);
517
  numbytes = msHexDecode(string_buf, bytes_out, 4);
518
  printf(
519
      "msHexDecode(%s, 4) = %d, bytes_out = %x, %x, %x, %x, %x, %x, %x, %x\n",
520
      string_buf, numbytes, bytes_out[0], bytes_out[1], bytes_out[2],
521
      bytes_out[3], bytes_out[4], bytes_out[5], bytes_out[6], bytes_out[7]);
522

523
  memset(bytes_out, 0, 8);
524
  numbytes = msHexDecode(string_buf, bytes_out, 20);
525
  printf(
526
      "msHexDecode(%s, 20) = %d, bytes_out = %x, %x, %x, %x, %x, %x, %x, %x\n",
527
      string_buf, numbytes, bytes_out[0], bytes_out[1], bytes_out[2],
528
      bytes_out[3], bytes_out[4], bytes_out[5], bytes_out[6], bytes_out[7]);
529

530
  /*
531
  ** Test loading encryption key
532
  */
533
  if (msReadEncryptionKeyFromFile("/tmp/test.key", encryption_key, NULL) !=
534
      MS_SUCCESS) {
535
    printf("msReadEncryptionKeyFromFile() = MS_FAILURE\n");
536
    printf("Aborting tests!\n");
537
    msWriteError(stderr);
538
    return -1;
539
  } else {
540
    msHexEncode(encryption_key, string_buf, MS_ENCRYPTION_KEY_SIZE);
541
    printf("msReadEncryptionKeyFromFile() returned '%s'\n", string_buf);
542
  }
543

544
  /*
545
  ** Test Encryption/Decryption
546
  */
547

548
  /* First with an 8 bytes input string (test boundaries) */
549
  msEncryptStringWithKey(encryption_key, "test1234", string_buf);
550
  printf("msEncryptStringWithKey('test1234') returned '%s'\n", string_buf);
551

552
  msDecryptStringWithKey(encryption_key, string_buf, string_buf2);
553
  printf("msDecryptStringWithKey('%s') returned '%s'\n", string_buf,
554
         string_buf2);
555

556
  /* Next with an 1 byte input string */
557
  msEncryptStringWithKey(encryption_key, "t", string_buf);
558
  printf("msEncryptStringWithKey('t') returned '%s'\n", string_buf);
559

560
  msDecryptStringWithKey(encryption_key, string_buf, string_buf2);
561
  printf("msDecryptStringWithKey('%s') returned '%s'\n", string_buf,
562
         string_buf2);
563

564
  /* Next with an 12 bytes input string */
565
  msEncryptStringWithKey(encryption_key, "test123456", string_buf);
566
  printf("msEncryptStringWithKey('test123456') returned '%s'\n", string_buf);
567

568
  msDecryptStringWithKey(encryption_key, string_buf, string_buf2);
569
  printf("msDecryptStringWithKey('%s') returned '%s'\n", string_buf,
570
         string_buf2);
571

572
  /*
573
  ** Test decryption with tokens
574
  */
575
  {
576
    char *pszBuf;
577
    mapObj *map;
578
    /* map = msNewMapObj(); */
579
    map = msLoadMap("/tmp/test.map", NULL);
580

581
    sprintf(string_buf2, "string with a {%s} encrypted token", string_buf);
582

583
    pszBuf = msDecryptStringTokens(map, string_buf2);
584
    if (pszBuf == NULL) {
585
      printf("msDecryptStringTokens() failed.\n");
586
      printf("Aborting tests!\n");
587
      msWriteError(stderr);
588
      return -1;
589
    } else {
590
      printf("msDecryptStringTokens('%s') returned '%s'\n", string_buf2,
591
             pszBuf);
592
    }
593
    msFree(pszBuf);
594
    msFreeMap(map);
595
  }
596

597
  return 0;
598
}
599

600
#endif /* TEST_MAPCRYPTO */
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc