GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: lib/libkeynote/keynote.l Lines: 0 120 0.0 %
Date: 2017-11-07 Branches: 0 134 0.0 %

Line Branch Exec Source
1
%{
2
/* $OpenBSD: keynote.l,v 1.24 2017/08/28 17:07:19 millert Exp $ */
3
/*
4
 * The author of this code is Angelos D. Keromytis (angelos@dsl.cis.upenn.edu)
5
 *
6
 * This code was written by Angelos D. Keromytis in Philadelphia, PA, USA,
7
 * in April-May 1998
8
 *
9
 * Copyright (C) 1998, 1999 by Angelos D. Keromytis.
10
 *
11
 * Permission to use, copy, and modify this software with or without fee
12
 * is hereby granted, provided that this entire notice is included in
13
 * all copies of any software which is or includes a copy or
14
 * modification of this software.
15
 *
16
 * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
17
 * IMPLIED WARRANTY. IN PARTICULAR, THE AUTHORS MAKES NO
18
 * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
19
 * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
20
 * PURPOSE.
21
 */
22
23
#include <sys/time.h>
24
#include <sys/types.h>
25
26
#include <ctype.h>
27
#include <regex.h>
28
#include <string.h>
29
#include <time.h>
30
#include <unistd.h>
31
32
#include "k.tab.h"
33
#include "keynote.h"
34
#include "assertion.h"
35
36
static void mystrncpy(char *, char *, int);
37
38
struct lex_list
39
{
40
    int   lex_type;
41
    void *lex_s;
42
};
43
44
static struct lex_list *keynote_lex_list = NULL;
45
static int    keynote_max_lex_list = 32;
46
static int    keynote_lex_counter = 0;
47
static int    first_tok = 0;
48
%}
49
digit		[0-9]
50
specnumber      [1-9][0-9]*
51
number		{digit}+
52
flt		{digit}+"."{digit}+
53
vstring		[a-zA-Z_][a-zA-Z0-9_]*
54
litstring	\"(((\\\n)|(\\.)|([^\\\n\"]))*)\"
55
variable	{vstring}
56
comment		"#"[^\n]*
57
%s ACTIONSTRING LOCALINIT KEYPREDICATE SIGNERINIT KEYNOTEVERSION
58
%pointer
59
%option noinput noyywrap never-interactive yylineno
60
%%
61
%{
62
    /*
63
     * Return a preset token, so we can have more than one grammars
64
     * in yacc.
65
     */
66
    extern int first_tok;
67
68
    if (first_tok)
69
    {
70
	int holdtok = first_tok;
71
72
	first_tok = 0;
73
	return holdtok;
74
    }
75
%}
76
77
<KEYPREDICATE>{specnumber}"-of"		{
78
					  knlval.intval = atoi(kntext);
79
					  return KOF;
80
					}
81
<ACTIONSTRING,KEYPREDICATE>"("		return OPENPAREN;
82
<ACTIONSTRING,KEYPREDICATE>")"		return CLOSEPAREN;
83
<ACTIONSTRING,KEYPREDICATE>"&&"		return AND;
84
<ACTIONSTRING,KEYPREDICATE>"||"		return OR;
85
<ACTIONSTRING>"+"			return PLUS;
86
<ACTIONSTRING>"->"              return HINT;
87
<ACTIONSTRING>"{"               return OPENBLOCK;
88
<ACTIONSTRING>"}"               return CLOSEBLOCK;
89
<ACTIONSTRING>";"               return SEMICOLON;
90
<ACTIONSTRING>"!"		return NOT;
91
<ACTIONSTRING>"~="		return REGEXP;
92
<ACTIONSTRING>"=="		return EQ;
93
<ACTIONSTRING>"!="		return NE;
94
<ACTIONSTRING>"<"		return LT;
95
<ACTIONSTRING>">"		return GT;
96
<ACTIONSTRING>"<="		return LE;
97
<ACTIONSTRING>">="		return GE;
98
<ACTIONSTRING>"-"		return MINUS;
99
<ACTIONSTRING>"*"		return MULT;
100
<ACTIONSTRING>"/"		return DIV;
101
<ACTIONSTRING>"%"		return MOD;
102
<ACTIONSTRING>"^"		return EXP;
103
"."		                return DOTT;
104
<ACTIONSTRING>"true"            return TRUE;
105
<ACTIONSTRING>"false"           return FALSE;
106
{comment}		/* eat up comments */
107
<LOCALINIT>"="	                return EQQ;
108
<KEYPREDICATE>"," 		return COMMA;
109
<ACTIONSTRING,KEYPREDICATE,SIGNERINIT,LOCALINIT>{variable} {
110
					int len;
111
                                        if (keynote_exceptionflag ||
112
					    keynote_donteval)
113
					{
114
					    knlval.string = NULL;
115
					    return VARIABLE;
116
					}
117
118
					len = strlen(kntext) + 1;
119
					knlval.string = calloc(len, sizeof(char));
120
                                        if (knlval.string == NULL)
121
					{
122
					    keynote_errno = ERROR_MEMORY;
123
					    return -1;
124
					}
125
		  	          	strlcpy(knlval.string, kntext, len);
126
					if (keynote_lex_add(knlval.string,
127
							    LEXTYPE_CHAR) ==
128
					    -1)
129
					  return -1;
130
		  	         	return VARIABLE;
131
			      	      }
132
"$"                             return DEREF;
133
<ACTIONSTRING>"@"	    	return OPENNUM;
134
<ACTIONSTRING>"&"	    	return OPENFLT;
135
<ACTIONSTRING>{flt}	      {
136
				knlval.doubval = atof(kntext);
137
				return FLOAT;
138
			      }
139
<KEYNOTEVERSION>{number}      {
140
				int len;
141
142
                                if (keynote_exceptionflag ||
143
				    keynote_donteval)
144
				{
145
				    knlval.string = NULL;
146
				    return STRING;
147
				}
148
149
				len = strlen(kntext) + 1;
150
				knlval.string = calloc(len, sizeof(char));
151
                                if (knlval.string == NULL)
152
				{
153
				    keynote_errno = ERROR_MEMORY;
154
				    return -1;
155
				}
156
		  	        strlcpy(knlval.string, kntext, len);
157
				if (keynote_lex_add(knlval.string,
158
						    LEXTYPE_CHAR) == -1)
159
				  return -1;
160
		  	        return STRING;
161
			      }
162
<ACTIONSTRING>{number}	      {
163
				knlval.intval = atoi(kntext);
164
				return NUM;
165
			      }
166
{litstring}                   {
167
                                if (keynote_exceptionflag ||
168
				    keynote_donteval)
169
				{
170
				    knlval.string = NULL;
171
				    return STRING;
172
				}
173
174
				knlval.string = calloc(strlen(kntext) - 1,
175
						       sizeof(char));
176
                                if (knlval.string == NULL)
177
				{
178
				    keynote_errno = ERROR_MEMORY;
179
				    return -1;
180
				}
181
182
				mystrncpy(knlval.string, kntext + 1,
183
					  strlen(kntext) - 2);
184
185
				if (keynote_lex_add(knlval.string,
186
						    LEXTYPE_CHAR) == -1)
187
				  return -1;
188
				return STRING;
189
                              }
190
[ \t\n]
191
.                             { keynote_errno = ERROR_SYNTAX;
192
                                return -1;
193
				REJECT; /* Avoid -Wall warning. Not reached */
194
                              }
195
%%
196
197
/*
198
 * Zap everything.
199
 */
200
static void
201
keynote_lex_zap(void)
202
{
203
    int i;
204
205
    if (keynote_lex_counter == 0)
206
      return;
207
208
    for (i = 0; i < keynote_max_lex_list; i++)
209
      if (keynote_lex_list[i].lex_s != NULL)
210
      {
211
	  switch (keynote_lex_list[i].lex_type)
212
	  {
213
	      case LEXTYPE_CHAR:
214
	          free(keynote_lex_list[i].lex_s);
215
		  break;
216
	  }
217
218
	  keynote_lex_counter--;
219
	  keynote_lex_list[i].lex_s = NULL;
220
	  keynote_lex_list[i].lex_type = 0;
221
      }
222
}
223
224
/*
225
 * Initialize.
226
 */
227
static int
228
keynote_lex_init(void)
229
{
230
    if (keynote_lex_list != NULL)
231
      memset(keynote_lex_list, 0,
232
	     keynote_max_lex_list * sizeof(struct lex_list));
233
    else
234
    {
235
	keynote_lex_list = calloc(keynote_max_lex_list,
236
					              sizeof(struct lex_list));
237
        if (keynote_lex_list == NULL)
238
	{
239
	    keynote_errno = ERROR_MEMORY;
240
	    return -1;
241
	}
242
    }
243
244
    return RESULT_TRUE;
245
}
246
247
/*
248
 * Add the string in a list of allocated but "dangling" memory references.
249
 * If out of memory, free the string and return -1 (and set keynote_errno).
250
 */
251
int
252
keynote_lex_add(void *s, int type)
253
{
254
    struct lex_list *p;
255
    int i;
256
257
    if (s == NULL)
258
      return RESULT_TRUE;
259
260
    for (i = 0; i < keynote_max_lex_list; i++)
261
      if (keynote_lex_list[i].lex_s == NULL)
262
      {
263
    	  keynote_lex_list[i].lex_s = (void *) s;
264
	  keynote_lex_list[i].lex_type = type;
265
	  keynote_lex_counter++;
266
     	  return RESULT_TRUE;
267
      }
268
269
    /* Not enough space, increase the size of the array */
270
    keynote_max_lex_list *= 2;
271
272
    p = (struct lex_list *) reallocarray(keynote_lex_list,
273
					 keynote_max_lex_list,
274
					 sizeof(struct lex_list));
275
    if (p == NULL)
276
    {
277
	switch (type)
278
	{
279
	    case LEXTYPE_CHAR:
280
	        free(s);
281
		break;
282
	}
283
284
        keynote_max_lex_list /= 2;
285
	keynote_errno = ERROR_MEMORY;
286
        return -1;
287
    }
288
289
    keynote_lex_list = p;
290
    keynote_lex_list[i].lex_s = s;
291
    keynote_lex_list[i++].lex_type = type;
292
    keynote_lex_counter++;
293
294
    /* Zero out the rest */
295
    memset(&(keynote_lex_list[i]), 0,
296
	   (keynote_max_lex_list - i) * sizeof(struct lex_list));
297
298
    return RESULT_TRUE;
299
}
300
301
/*
302
 * Remove string.
303
 */
304
void
305
keynote_lex_remove(void *s)
306
{
307
    int i;
308
309
    for (i = 0; i < keynote_max_lex_list; i++)
310
      if (keynote_lex_list[i].lex_s == s)
311
      {
312
	  memset(&(keynote_lex_list[i]), 0, sizeof(struct lex_list));
313
	  keynote_lex_counter--;
314
	  return;
315
      }
316
}
317
318
/*
319
 * Return RESULT_TRUE if character is octal digit, RESULT_FALSE otherwise.
320
 */
321
static int
322
is_octal(char c)
323
{
324
    switch (c)
325
    {
326
	case '0': case '1': case '2': case '3':
327
	case '4': case '5': case '6': case '7':
328
	    return RESULT_TRUE;
329
330
	default:
331
	    return RESULT_FALSE;
332
    }
333
}
334
335
/*
336
 * Return octal value (non-zero) if argument starts with such a
337
 * representation, otherwise 0.
338
 */
339
static unsigned char
340
get_octal(char *s, int len, int *adv)
341
{
342
    unsigned char res = 0;
343
344
    if (*s == '0')
345
    {
346
	if (len > 0)
347
	{
348
	    if (is_octal(*(s + 1)))
349
	    {
350
		res = *(s + 1) - '0';
351
		*adv = 2;
352
353
		if (is_octal(*(s + 2)) && (len - 1 > 0))
354
		{
355
		    res = res * 8 + (*(s + 2) - '0');
356
		    *adv = 3;
357
		}
358
	    }
359
	}
360
    }
361
    else
362
      if (is_octal(*s) && (len - 1 > 0))  /* Non-zero leading */
363
      {
364
	  if (is_octal(*(s + 1)) &&
365
	      is_octal(*(s + 2)))
366
	  {
367
	      *adv = 3;
368
	      res = (((*s) - '0') * 64) +
369
		    (((*(s + 1)) - '0') * 8) +
370
		    ((*(s + 2)) - '0');
371
	  }
372
      }
373
374
    return res;
375
}
376
377
/*
378
 * Copy at most len characters to string s1 from string s2, taking
379
 * care of escaped characters in the process. String s1 is assumed
380
 * to have enough space, and be zero'ed.
381
 */
382
static void
383
mystrncpy(char *s1, char *s2, int len)
384
{
385
    unsigned char c;
386
    int advance;
387
388
    if (len == 0)
389
      return;
390
391
    while (len-- > 0)
392
    {
393
        if (*s2 == '\\')
394
	{
395
	    s2++;
396
397
	    if (len-- <= 0)
398
	      break;
399
400
	    if (*s2 == '\n')
401
	    {
402
		while (isspace((unsigned char)*(++s2)) && (len-- > 0))
403
		  ;
404
	    }
405
	    else
406
	      if ((c = get_octal(s2, len, &advance)) != 0)
407
	      {
408
		  len -= advance - 1;
409
		  s2 += advance;
410
		  *s1++ = c;
411
	      }
412
	      else
413
		if (*s2 == 'n')  /* Newline */
414
		{
415
		    *s1++ = '\n';
416
		    s2++;
417
		}
418
		else
419
		  if (*s2 == 't')  /* Tab */
420
		  {
421
		      *s1++ = '\t';
422
		      s2++;
423
		  }
424
		  else
425
		    if (*s2 == 'r')  /* Linefeed */
426
		    {
427
			*s1++ = '\r';
428
			s2++;
429
		    }
430
		    else
431
		      if (*s2 == 'f')  /* Formfeed */
432
		      {
433
			  *s1++ = '\f';
434
			  s2++;
435
		      }
436
		      else
437
			if ((*s1++ = *s2++) == 0)
438
			  break;
439
440
	    continue;
441
	}
442
443
        if ((*s1++ = *s2++) == 0)
444
	  break;
445
     }
446
}
447
448
/*
449
 * Evaluate an assertion, with as->as_result holding the result.
450
 * Return RESULT_TRUE if all ok. Also return the result.
451
 */
452
int
453
keynote_evaluate_assertion(struct assertion *as)
454
{
455
    YY_BUFFER_STATE keynote_bs;
456
457
    /* Non-existent Conditions field means highest return value */
458
    if (as->as_conditions_s == NULL)
459
    {
460
	as->as_result = keynote_current_session->ks_values_num - 1;
461
	return RESULT_TRUE;
462
    }
463
464
    if (keynote_lex_init() != RESULT_TRUE)
465
      return -1;
466
467
    keynote_used_variable = 0;
468
    keynote_init_list = as->as_env;     /* Setup the local-init var list */
469
470
    keynote_bs = kn_scan_bytes(as->as_conditions_s,
471
			       as->as_conditions_e - as->as_conditions_s);
472
    BEGIN(ACTIONSTRING);	/* We're doing conditions-string parsing */
473
    first_tok = ACTSTR;
474
    as->as_result = 0;
475
    keynote_returnvalue = 0;
476
477
    switch (knparse())
478
    {
479
	case 1:  /* Fall through */
480
	    keynote_errno = ERROR_SYNTAX;
481
	case -1:
482
	    as->as_result = 0;
483
	    break;
484
485
	case 0:
486
	    as->as_result = keynote_returnvalue;
487
	    break;
488
    }
489
490
    keynote_env_cleanup(&keynote_temp_list, 1);
491
    keynote_lex_zap();
492
    kn_delete_buffer(keynote_bs);
493
494
    keynote_used_variable = 0;
495
    keynote_returnvalue = 0;
496
    keynote_temp_list = NULL;
497
    keynote_init_list = NULL;
498
499
    if (keynote_errno != 0)
500
      return -1;
501
    else
502
      return RESULT_TRUE;
503
}
504
505
/*
506
 * Parse/evaluate a key predicate field.
507
 * Store keys in key predicate as keylist in as->as_keylist, if second
508
 * argument is true.
509
 */
510
int
511
keynote_parse_keypred(struct assertion *as, int record)
512
{
513
    YY_BUFFER_STATE keypred_state;
514
    int p = 0, err;
515
516
    if (as->as_keypred_s == NULL)
517
      return keynote_current_session->ks_values_num - 1;
518
519
    if (keynote_lex_init() != RESULT_TRUE)
520
      return -1;
521
522
    keynote_used_variable = 0;
523
    keynote_returnvalue = 0;
524
    keynote_justrecord = record; /* Just want the list of keys in predicate */
525
    keynote_init_list = as->as_env;
526
527
    keypred_state = kn_scan_bytes(as->as_keypred_s,
528
				  as->as_keypred_e - as->as_keypred_s);
529
    BEGIN(KEYPREDICATE);
530
    first_tok = KEYPRE;
531
532
    err = knparse();
533
    if (err != 0)
534
      if (keynote_errno == 0)
535
	keynote_errno = ERROR_SYNTAX;
536
537
    kn_delete_buffer(keypred_state);
538
    keynote_lex_zap();
539
    keynote_cleanup_kth();
540
541
    keynote_init_list = NULL;
542
    keynote_justrecord = 0;
543
    p = keynote_returnvalue;
544
    keynote_returnvalue = 0;
545
546
    if (record)
547
    {
548
	if (keynote_errno != 0)
549
	{
550
	    keynote_keylist_free(keynote_keypred_keylist);
551
	    keynote_keypred_keylist = NULL;
552
	    return -1;
553
	}
554
	else
555
	{
556
	    /* Mark for re-processing if/when environment changes */
557
	    if (keynote_used_variable)
558
	    {
559
		keynote_used_variable = 0;
560
		as->as_internalflags |= ASSERT_IFLAG_WEIRDLICS;
561
	    }
562
563
	    if (as->as_keylist)
564
              keynote_keylist_free(as->as_keylist);
565
	    as->as_keylist = keynote_keypred_keylist;
566
	    keynote_keypred_keylist = NULL;
567
	    return RESULT_TRUE;
568
	}
569
    }
570
    else
571
      return p;
572
}
573
574
/* Evaluate an authorizer or signature field. Return RESULT_TRUE on success.
575
 * Store key in as->as_authorizer. Second argument is set only for Authorizer
576
 * field parsing.
577
 */
578
int
579
keynote_evaluate_authorizer(struct assertion *as, int flag)
580
{
581
    YY_BUFFER_STATE authorizer_state;
582
    int err;
583
584
    if (keynote_lex_init() != RESULT_TRUE)
585
      return -1;
586
587
    keynote_init_list = as->as_env;
588
    keynote_justrecord = 1;
589
    keynote_used_variable = 0;
590
591
    if ((flag) && (as->as_authorizer != NULL))
592
    {
593
	keynote_free_key(as->as_authorizer, as->as_signeralgorithm);
594
	as->as_authorizer = NULL;
595
    }
596
597
    if (flag)
598
      authorizer_state = kn_scan_bytes(as->as_authorizer_string_s,
599
				       as->as_authorizer_string_e -
600
				       as->as_authorizer_string_s);
601
    else
602
      authorizer_state = kn_scan_bytes(as->as_signature_string_s,
603
				       as->as_signature_string_e -
604
				       as->as_signature_string_s);
605
606
    BEGIN(SIGNERINIT);
607
    if (flag)
608
      first_tok = SIGNERKEY;
609
    else
610
      first_tok = SIGNATUREENTRY;
611
612
    err = knparse();
613
    if ((err != 0) && (keynote_errno == 0))
614
      keynote_errno = ERROR_SYNTAX;
615
616
    kn_delete_buffer(authorizer_state);
617
    keynote_lex_zap();
618
619
    keynote_justrecord = 0;
620
    keynote_init_list = NULL;
621
    keynote_returnvalue = 0;
622
623
    if (keynote_keypred_keylist != NULL)
624
    {
625
	if (flag)
626
	{
627
	    if (keynote_used_variable)
628
	      as->as_internalflags |= ASSERT_IFLAG_WEIRDAUTH;
629
630
	    as->as_authorizer = keynote_keypred_keylist->key_key;
631
	    as->as_signeralgorithm = keynote_keypred_keylist->key_alg;
632
	}
633
	else
634
	{
635
	    if (keynote_used_variable)
636
	      as->as_internalflags |= ASSERT_IFLAG_WEIRDSIG;
637
638
	    as->as_signature = keynote_keypred_keylist->key_key;
639
	}
640
641
	keynote_keypred_keylist->key_key = NULL;
642
	keynote_keylist_free(keynote_keypred_keylist);
643
	keynote_keypred_keylist = NULL;
644
    }
645
646
    keynote_used_variable = 0;
647
648
    if (keynote_errno != 0)
649
      return -1;
650
    else
651
      return RESULT_TRUE;
652
}
653
654
/*
655
 * Exportable front-end to keynote_get_private_key().
656
 */
657
char *
658
kn_get_string(char *buf)
659
{
660
    return keynote_get_private_key(buf);
661
}
662
663
/*
664
 * Parse a private key -- actually, it can deal with any kind of string.
665
 */
666
char *
667
keynote_get_private_key(char *buf)
668
{
669
    YY_BUFFER_STATE pkey;
670
    char *s;
671
    int err;
672
673
    if (keynote_lex_init() != RESULT_TRUE)
674
      return NULL;
675
676
    keynote_privkey = NULL;
677
    pkey = kn_scan_bytes(buf, strlen(buf));
678
    first_tok = PRIVATEKEY;
679
    err = knparse();
680
    kn_delete_buffer(pkey);
681
    keynote_lex_zap();
682
683
    if (err != 0)
684
    {
685
	if (keynote_privkey != NULL)
686
	{
687
	    free(keynote_privkey);
688
	    keynote_privkey = NULL;
689
	}
690
691
	if (keynote_errno == 0)
692
	  keynote_errno = ERROR_SYNTAX;
693
694
	return NULL;
695
    }
696
697
    s = keynote_privkey;
698
    keynote_privkey = NULL;
699
    return s;
700
}
701
702
/*
703
 * Parse Local-Constants and KeyNote-Version fields.
704
 */
705
struct environment *
706
keynote_get_envlist(char *buf, char *bufend, int whichfield)
707
{
708
    struct environment *en = NULL;
709
    YY_BUFFER_STATE localinit_state;
710
    int err;
711
712
    if (keynote_lex_init() != RESULT_TRUE)
713
      return NULL;
714
715
    localinit_state = kn_scan_bytes(buf, bufend - buf);
716
    if (whichfield == 0)
717
    {
718
	BEGIN(LOCALINIT);	/* We're doing Local-Constants parsing */
719
	first_tok = LOCINI;
720
    }
721
    else
722
    {
723
	BEGIN(KEYNOTEVERSION);	/* KeyNote-Version parsing */
724
      	first_tok = KNVERSION;
725
    }
726
727
    err = knparse();
728
    if (err != 0)
729
      if (keynote_errno == 0)
730
	keynote_errno = ERROR_SYNTAX;
731
732
    kn_delete_buffer(localinit_state);
733
    keynote_lex_zap();
734
735
    if (!whichfield)
736
    {
737
	if (keynote_errno != 0)
738
	  keynote_env_cleanup(&keynote_init_list, 1);
739
	else
740
	  en = keynote_init_list;
741
742
    	keynote_init_list = NULL;
743
    }
744
745
    /* Avoid compiler (-Wall) warnings. Never reached. */
746
    if (0)
747
    {
748
	yyunput(0, NULL);
749
    }
750
751
    return en;
752
}