1983e9580Sangelos %{ 2*b299522fSmillert /* $OpenBSD: keynote.l,v 1.24 2017/08/28 17:07:19 millert Exp $ */ 3983e9580Sangelos /* 4983e9580Sangelos * The author of this code is Angelos D. Keromytis (angelos@dsl.cis.upenn.edu) 5983e9580Sangelos * 6983e9580Sangelos * This code was written by Angelos D. Keromytis in Philadelphia, PA, USA, 7983e9580Sangelos * in April-May 1998 8983e9580Sangelos * 9983e9580Sangelos * Copyright (C) 1998, 1999 by Angelos D. Keromytis. 10983e9580Sangelos * 115e4ac158Sderaadt * Permission to use, copy, and modify this software with or without fee 12983e9580Sangelos * is hereby granted, provided that this entire notice is included in 13983e9580Sangelos * all copies of any software which is or includes a copy or 14983e9580Sangelos * modification of this software. 15983e9580Sangelos * 16983e9580Sangelos * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR 17983e9580Sangelos * IMPLIED WARRANTY. IN PARTICULAR, THE AUTHORS MAKES NO 18983e9580Sangelos * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE 19983e9580Sangelos * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR 20983e9580Sangelos * PURPOSE. 21983e9580Sangelos */ 22983e9580Sangelos 23e0758482Smsf #include <sys/time.h> 24983e9580Sangelos #include <sys/types.h> 25e0758482Smsf 26983e9580Sangelos #include <ctype.h> 2785616838Smsf #include <regex.h> 28983e9580Sangelos #include <string.h> 29e0758482Smsf #include <time.h> 309186b70cSangelos #include <unistd.h> 31a8a6ad51Sangelos 32983e9580Sangelos #include "k.tab.h" 33a8a6ad51Sangelos #include "keynote.h" 34983e9580Sangelos #include "assertion.h" 35983e9580Sangelos 36983e9580Sangelos static void mystrncpy(char *, char *, int); 37983e9580Sangelos 38983e9580Sangelos struct lex_list 39983e9580Sangelos { 40983e9580Sangelos int lex_type; 41983e9580Sangelos void *lex_s; 42983e9580Sangelos }; 43983e9580Sangelos 44313d0fe7Smmcc static struct lex_list *keynote_lex_list = NULL; 45983e9580Sangelos static int keynote_max_lex_list = 32; 46983e9580Sangelos static int keynote_lex_counter = 0; 47983e9580Sangelos static int first_tok = 0; 48983e9580Sangelos %} 49983e9580Sangelos digit [0-9] 50983e9580Sangelos specnumber [1-9][0-9]* 514812cf71Sangelos number {digit}+ 524812cf71Sangelos flt {digit}+"."{digit}+ 53983e9580Sangelos vstring [a-zA-Z_][a-zA-Z0-9_]* 54f416c374Sangelos litstring \"(((\\\n)|(\\.)|([^\\\n\"]))*)\" 55983e9580Sangelos variable {vstring} 56983e9580Sangelos comment "#"[^\n]* 57983e9580Sangelos %s ACTIONSTRING LOCALINIT KEYPREDICATE SIGNERINIT KEYNOTEVERSION 58983e9580Sangelos %pointer 59*b299522fSmillert %option noinput noyywrap never-interactive yylineno 60983e9580Sangelos %% 61983e9580Sangelos %{ 62983e9580Sangelos /* 63983e9580Sangelos * Return a preset token, so we can have more than one grammars 64983e9580Sangelos * in yacc. 65983e9580Sangelos */ 66983e9580Sangelos extern int first_tok; 67983e9580Sangelos 68983e9580Sangelos if (first_tok) 69983e9580Sangelos { 70983e9580Sangelos int holdtok = first_tok; 71983e9580Sangelos 72983e9580Sangelos first_tok = 0; 73983e9580Sangelos return holdtok; 74983e9580Sangelos } 75983e9580Sangelos %} 76983e9580Sangelos 77983e9580Sangelos <KEYPREDICATE>{specnumber}"-of" { 78983e9580Sangelos knlval.intval = atoi(kntext); 79983e9580Sangelos return KOF; 80983e9580Sangelos } 81983e9580Sangelos <ACTIONSTRING,KEYPREDICATE>"(" return OPENPAREN; 82983e9580Sangelos <ACTIONSTRING,KEYPREDICATE>")" return CLOSEPAREN; 83983e9580Sangelos <ACTIONSTRING,KEYPREDICATE>"&&" return AND; 84983e9580Sangelos <ACTIONSTRING,KEYPREDICATE>"||" return OR; 85983e9580Sangelos <ACTIONSTRING>"+" return PLUS; 86983e9580Sangelos <ACTIONSTRING>"->" return HINT; 87983e9580Sangelos <ACTIONSTRING>"{" return OPENBLOCK; 88983e9580Sangelos <ACTIONSTRING>"}" return CLOSEBLOCK; 89983e9580Sangelos <ACTIONSTRING>";" return SEMICOLON; 90983e9580Sangelos <ACTIONSTRING>"!" return NOT; 91983e9580Sangelos <ACTIONSTRING>"~=" return REGEXP; 92983e9580Sangelos <ACTIONSTRING>"==" return EQ; 93983e9580Sangelos <ACTIONSTRING>"!=" return NE; 94983e9580Sangelos <ACTIONSTRING>"<" return LT; 95983e9580Sangelos <ACTIONSTRING>">" return GT; 96983e9580Sangelos <ACTIONSTRING>"<=" return LE; 97983e9580Sangelos <ACTIONSTRING>">=" return GE; 98983e9580Sangelos <ACTIONSTRING>"-" return MINUS; 99983e9580Sangelos <ACTIONSTRING>"*" return MULT; 100983e9580Sangelos <ACTIONSTRING>"/" return DIV; 101983e9580Sangelos <ACTIONSTRING>"%" return MOD; 102983e9580Sangelos <ACTIONSTRING>"^" return EXP; 103983e9580Sangelos "." return DOTT; 104983e9580Sangelos <ACTIONSTRING>"true" return TRUE; 105983e9580Sangelos <ACTIONSTRING>"false" return FALSE; 106983e9580Sangelos {comment} /* eat up comments */ 107983e9580Sangelos <LOCALINIT>"=" return EQQ; 108983e9580Sangelos <KEYPREDICATE>"," return COMMA; 109983e9580Sangelos <ACTIONSTRING,KEYPREDICATE,SIGNERINIT,LOCALINIT>{variable} { 110f91597c4Sderaadt int len; 111983e9580Sangelos if (keynote_exceptionflag || 112983e9580Sangelos keynote_donteval) 113983e9580Sangelos { 114313d0fe7Smmcc knlval.string = NULL; 115983e9580Sangelos return VARIABLE; 116983e9580Sangelos } 117983e9580Sangelos 118f91597c4Sderaadt len = strlen(kntext) + 1; 119f91597c4Sderaadt knlval.string = calloc(len, sizeof(char)); 120313d0fe7Smmcc if (knlval.string == NULL) 121983e9580Sangelos { 122983e9580Sangelos keynote_errno = ERROR_MEMORY; 123983e9580Sangelos return -1; 124983e9580Sangelos } 125f91597c4Sderaadt strlcpy(knlval.string, kntext, len); 126983e9580Sangelos if (keynote_lex_add(knlval.string, 127983e9580Sangelos LEXTYPE_CHAR) == 128983e9580Sangelos -1) 129983e9580Sangelos return -1; 130983e9580Sangelos return VARIABLE; 131983e9580Sangelos } 132983e9580Sangelos "$" return DEREF; 133983e9580Sangelos <ACTIONSTRING>"@" return OPENNUM; 134983e9580Sangelos <ACTIONSTRING>"&" return OPENFLT; 135983e9580Sangelos <ACTIONSTRING>{flt} { 136983e9580Sangelos knlval.doubval = atof(kntext); 137983e9580Sangelos return FLOAT; 138983e9580Sangelos } 139983e9580Sangelos <KEYNOTEVERSION>{number} { 140f91597c4Sderaadt int len; 141f91597c4Sderaadt 142983e9580Sangelos if (keynote_exceptionflag || 143983e9580Sangelos keynote_donteval) 144983e9580Sangelos { 145313d0fe7Smmcc knlval.string = NULL; 146983e9580Sangelos return STRING; 147983e9580Sangelos } 148983e9580Sangelos 149f91597c4Sderaadt len = strlen(kntext) + 1; 150f91597c4Sderaadt knlval.string = calloc(len, sizeof(char)); 151313d0fe7Smmcc if (knlval.string == NULL) 152983e9580Sangelos { 153983e9580Sangelos keynote_errno = ERROR_MEMORY; 154983e9580Sangelos return -1; 155983e9580Sangelos } 156f91597c4Sderaadt strlcpy(knlval.string, kntext, len); 157983e9580Sangelos if (keynote_lex_add(knlval.string, 158983e9580Sangelos LEXTYPE_CHAR) == -1) 159983e9580Sangelos return -1; 160983e9580Sangelos return STRING; 161983e9580Sangelos } 162983e9580Sangelos <ACTIONSTRING>{number} { 163983e9580Sangelos knlval.intval = atoi(kntext); 164983e9580Sangelos return NUM; 165983e9580Sangelos } 166983e9580Sangelos {litstring} { 167983e9580Sangelos if (keynote_exceptionflag || 168983e9580Sangelos keynote_donteval) 169983e9580Sangelos { 170313d0fe7Smmcc knlval.string = NULL; 171983e9580Sangelos return STRING; 172983e9580Sangelos } 173983e9580Sangelos 174983e9580Sangelos knlval.string = calloc(strlen(kntext) - 1, 175983e9580Sangelos sizeof(char)); 176313d0fe7Smmcc if (knlval.string == NULL) 177983e9580Sangelos { 178983e9580Sangelos keynote_errno = ERROR_MEMORY; 179983e9580Sangelos return -1; 180983e9580Sangelos } 181983e9580Sangelos 182983e9580Sangelos mystrncpy(knlval.string, kntext + 1, 183983e9580Sangelos strlen(kntext) - 2); 184983e9580Sangelos 185983e9580Sangelos if (keynote_lex_add(knlval.string, 186983e9580Sangelos LEXTYPE_CHAR) == -1) 187983e9580Sangelos return -1; 188983e9580Sangelos return STRING; 189983e9580Sangelos } 190983e9580Sangelos [ \t\n] 191983e9580Sangelos . { keynote_errno = ERROR_SYNTAX; 192983e9580Sangelos return -1; 1934812cf71Sangelos REJECT; /* Avoid -Wall warning. Not reached */ 194983e9580Sangelos } 195983e9580Sangelos %% 196983e9580Sangelos 197983e9580Sangelos /* 198983e9580Sangelos * Zap everything. 199983e9580Sangelos */ 200983e9580Sangelos static void 201983e9580Sangelos keynote_lex_zap(void) 202983e9580Sangelos { 203983e9580Sangelos int i; 204983e9580Sangelos 205983e9580Sangelos if (keynote_lex_counter == 0) 206983e9580Sangelos return; 207983e9580Sangelos 208983e9580Sangelos for (i = 0; i < keynote_max_lex_list; i++) 209313d0fe7Smmcc if (keynote_lex_list[i].lex_s != NULL) 210983e9580Sangelos { 211983e9580Sangelos switch (keynote_lex_list[i].lex_type) 212983e9580Sangelos { 213983e9580Sangelos case LEXTYPE_CHAR: 214983e9580Sangelos free(keynote_lex_list[i].lex_s); 215983e9580Sangelos break; 216983e9580Sangelos } 217983e9580Sangelos 218983e9580Sangelos keynote_lex_counter--; 219313d0fe7Smmcc keynote_lex_list[i].lex_s = NULL; 220983e9580Sangelos keynote_lex_list[i].lex_type = 0; 221983e9580Sangelos } 222983e9580Sangelos } 223983e9580Sangelos 224983e9580Sangelos /* 225983e9580Sangelos * Initialize. 226983e9580Sangelos */ 227983e9580Sangelos static int 228983e9580Sangelos keynote_lex_init(void) 229983e9580Sangelos { 230313d0fe7Smmcc if (keynote_lex_list != NULL) 231983e9580Sangelos memset(keynote_lex_list, 0, 232983e9580Sangelos keynote_max_lex_list * sizeof(struct lex_list)); 233983e9580Sangelos else 234983e9580Sangelos { 235313d0fe7Smmcc keynote_lex_list = calloc(keynote_max_lex_list, 236983e9580Sangelos sizeof(struct lex_list)); 237313d0fe7Smmcc if (keynote_lex_list == NULL) 238983e9580Sangelos { 239983e9580Sangelos keynote_errno = ERROR_MEMORY; 240983e9580Sangelos return -1; 241983e9580Sangelos } 242983e9580Sangelos } 243983e9580Sangelos 244983e9580Sangelos return RESULT_TRUE; 245983e9580Sangelos } 246983e9580Sangelos 247983e9580Sangelos /* 248983e9580Sangelos * Add the string in a list of allocated but "dangling" memory references. 249983e9580Sangelos * If out of memory, free the string and return -1 (and set keynote_errno). 250983e9580Sangelos */ 251983e9580Sangelos int 252983e9580Sangelos keynote_lex_add(void *s, int type) 253983e9580Sangelos { 254983e9580Sangelos struct lex_list *p; 255983e9580Sangelos int i; 256983e9580Sangelos 257313d0fe7Smmcc if (s == NULL) 258983e9580Sangelos return RESULT_TRUE; 259983e9580Sangelos 260983e9580Sangelos for (i = 0; i < keynote_max_lex_list; i++) 261313d0fe7Smmcc if (keynote_lex_list[i].lex_s == NULL) 262983e9580Sangelos { 263983e9580Sangelos keynote_lex_list[i].lex_s = (void *) s; 264983e9580Sangelos keynote_lex_list[i].lex_type = type; 265983e9580Sangelos keynote_lex_counter++; 266983e9580Sangelos return RESULT_TRUE; 267983e9580Sangelos } 268983e9580Sangelos 269983e9580Sangelos /* Not enough space, increase the size of the array */ 270983e9580Sangelos keynote_max_lex_list *= 2; 271983e9580Sangelos 272862a1c7fSbluhm p = (struct lex_list *) reallocarray(keynote_lex_list, 273862a1c7fSbluhm keynote_max_lex_list, 274983e9580Sangelos sizeof(struct lex_list)); 275313d0fe7Smmcc if (p == NULL) 276983e9580Sangelos { 277983e9580Sangelos switch (type) 278983e9580Sangelos { 279983e9580Sangelos case LEXTYPE_CHAR: 280983e9580Sangelos free(s); 281983e9580Sangelos break; 282983e9580Sangelos } 283983e9580Sangelos 284984ef80bSangelos keynote_max_lex_list /= 2; 285983e9580Sangelos keynote_errno = ERROR_MEMORY; 286983e9580Sangelos return -1; 287983e9580Sangelos } 288983e9580Sangelos 289441ae911Sderaadt keynote_lex_list = p; 290983e9580Sangelos keynote_lex_list[i].lex_s = s; 291983e9580Sangelos keynote_lex_list[i++].lex_type = type; 292983e9580Sangelos keynote_lex_counter++; 293983e9580Sangelos 294983e9580Sangelos /* Zero out the rest */ 295983e9580Sangelos memset(&(keynote_lex_list[i]), 0, 296983e9580Sangelos (keynote_max_lex_list - i) * sizeof(struct lex_list)); 297983e9580Sangelos 298983e9580Sangelos return RESULT_TRUE; 299983e9580Sangelos } 300983e9580Sangelos 301983e9580Sangelos /* 302983e9580Sangelos * Remove string. 303983e9580Sangelos */ 304983e9580Sangelos void 305983e9580Sangelos keynote_lex_remove(void *s) 306983e9580Sangelos { 307983e9580Sangelos int i; 308983e9580Sangelos 309983e9580Sangelos for (i = 0; i < keynote_max_lex_list; i++) 310983e9580Sangelos if (keynote_lex_list[i].lex_s == s) 311983e9580Sangelos { 312983e9580Sangelos memset(&(keynote_lex_list[i]), 0, sizeof(struct lex_list)); 313983e9580Sangelos keynote_lex_counter--; 314983e9580Sangelos return; 315983e9580Sangelos } 316983e9580Sangelos } 317983e9580Sangelos 318983e9580Sangelos /* 319983e9580Sangelos * Return RESULT_TRUE if character is octal digit, RESULT_FALSE otherwise. 320983e9580Sangelos */ 321983e9580Sangelos static int 322983e9580Sangelos is_octal(char c) 323983e9580Sangelos { 324983e9580Sangelos switch (c) 325983e9580Sangelos { 326983e9580Sangelos case '0': case '1': case '2': case '3': 327983e9580Sangelos case '4': case '5': case '6': case '7': 328983e9580Sangelos return RESULT_TRUE; 329983e9580Sangelos 330983e9580Sangelos default: 331983e9580Sangelos return RESULT_FALSE; 332983e9580Sangelos } 333983e9580Sangelos } 334983e9580Sangelos 335983e9580Sangelos /* 336983e9580Sangelos * Return octal value (non-zero) if argument starts with such a 337983e9580Sangelos * representation, otherwise 0. 338983e9580Sangelos */ 339983e9580Sangelos static unsigned char 340983e9580Sangelos get_octal(char *s, int len, int *adv) 341983e9580Sangelos { 342983e9580Sangelos unsigned char res = 0; 343983e9580Sangelos 344983e9580Sangelos if (*s == '0') 345983e9580Sangelos { 346983e9580Sangelos if (len > 0) 347983e9580Sangelos { 348983e9580Sangelos if (is_octal(*(s + 1))) 349983e9580Sangelos { 350983e9580Sangelos res = *(s + 1) - '0'; 351983e9580Sangelos *adv = 2; 352983e9580Sangelos 353983e9580Sangelos if (is_octal(*(s + 2)) && (len - 1 > 0)) 354983e9580Sangelos { 355983e9580Sangelos res = res * 8 + (*(s + 2) - '0'); 356983e9580Sangelos *adv = 3; 357983e9580Sangelos } 358983e9580Sangelos } 359983e9580Sangelos } 360983e9580Sangelos } 361983e9580Sangelos else 362983e9580Sangelos if (is_octal(*s) && (len - 1 > 0)) /* Non-zero leading */ 363983e9580Sangelos { 364983e9580Sangelos if (is_octal(*(s + 1)) && 365983e9580Sangelos is_octal(*(s + 2))) 366983e9580Sangelos { 367983e9580Sangelos *adv = 3; 368983e9580Sangelos res = (((*s) - '0') * 64) + 369983e9580Sangelos (((*(s + 1)) - '0') * 8) + 370983e9580Sangelos ((*(s + 2)) - '0'); 371983e9580Sangelos } 372983e9580Sangelos } 373983e9580Sangelos 374983e9580Sangelos return res; 375983e9580Sangelos } 376983e9580Sangelos 377983e9580Sangelos /* 378983e9580Sangelos * Copy at most len characters to string s1 from string s2, taking 379983e9580Sangelos * care of escaped characters in the process. String s1 is assumed 380983e9580Sangelos * to have enough space, and be zero'ed. 381983e9580Sangelos */ 382983e9580Sangelos static void 383983e9580Sangelos mystrncpy(char *s1, char *s2, int len) 384983e9580Sangelos { 385983e9580Sangelos unsigned char c; 386983e9580Sangelos int advance; 387983e9580Sangelos 388983e9580Sangelos if (len == 0) 389983e9580Sangelos return; 390983e9580Sangelos 391983e9580Sangelos while (len-- > 0) 392983e9580Sangelos { 393983e9580Sangelos if (*s2 == '\\') 394983e9580Sangelos { 395983e9580Sangelos s2++; 396983e9580Sangelos 397983e9580Sangelos if (len-- <= 0) 398983e9580Sangelos break; 399983e9580Sangelos 400983e9580Sangelos if (*s2 == '\n') 401983e9580Sangelos { 40280c62621Sderaadt while (isspace((unsigned char)*(++s2)) && (len-- > 0)) 403983e9580Sangelos ; 404983e9580Sangelos } 405983e9580Sangelos else 406983e9580Sangelos if ((c = get_octal(s2, len, &advance)) != 0) 407983e9580Sangelos { 408983e9580Sangelos len -= advance - 1; 409983e9580Sangelos s2 += advance; 410983e9580Sangelos *s1++ = c; 411983e9580Sangelos } 412983e9580Sangelos else 413983e9580Sangelos if (*s2 == 'n') /* Newline */ 414983e9580Sangelos { 415983e9580Sangelos *s1++ = '\n'; 416983e9580Sangelos s2++; 417983e9580Sangelos } 418983e9580Sangelos else 419983e9580Sangelos if (*s2 == 't') /* Tab */ 420983e9580Sangelos { 421983e9580Sangelos *s1++ = '\t'; 422983e9580Sangelos s2++; 423983e9580Sangelos } 424983e9580Sangelos else 425983e9580Sangelos if (*s2 == 'r') /* Linefeed */ 426983e9580Sangelos { 427983e9580Sangelos *s1++ = '\r'; 428983e9580Sangelos s2++; 429983e9580Sangelos } 430983e9580Sangelos else 431983e9580Sangelos if (*s2 == 'f') /* Formfeed */ 432983e9580Sangelos { 433983e9580Sangelos *s1++ = '\f'; 434983e9580Sangelos s2++; 435983e9580Sangelos } 436983e9580Sangelos else 437983e9580Sangelos if ((*s1++ = *s2++) == 0) 438983e9580Sangelos break; 439983e9580Sangelos 440983e9580Sangelos continue; 441983e9580Sangelos } 442983e9580Sangelos 443983e9580Sangelos if ((*s1++ = *s2++) == 0) 444983e9580Sangelos break; 445983e9580Sangelos } 446983e9580Sangelos } 447983e9580Sangelos 448983e9580Sangelos /* 449983e9580Sangelos * Evaluate an assertion, with as->as_result holding the result. 450983e9580Sangelos * Return RESULT_TRUE if all ok. Also return the result. 451983e9580Sangelos */ 452983e9580Sangelos int 453983e9580Sangelos keynote_evaluate_assertion(struct assertion *as) 454983e9580Sangelos { 455983e9580Sangelos YY_BUFFER_STATE keynote_bs; 456983e9580Sangelos 4576957a4a4Sjmc /* Non-existent Conditions field means highest return value */ 458313d0fe7Smmcc if (as->as_conditions_s == NULL) 459983e9580Sangelos { 460983e9580Sangelos as->as_result = keynote_current_session->ks_values_num - 1; 461983e9580Sangelos return RESULT_TRUE; 462983e9580Sangelos } 463983e9580Sangelos 464983e9580Sangelos if (keynote_lex_init() != RESULT_TRUE) 465983e9580Sangelos return -1; 466983e9580Sangelos 467983e9580Sangelos keynote_used_variable = 0; 468983e9580Sangelos keynote_init_list = as->as_env; /* Setup the local-init var list */ 469983e9580Sangelos 470983e9580Sangelos keynote_bs = kn_scan_bytes(as->as_conditions_s, 471983e9580Sangelos as->as_conditions_e - as->as_conditions_s); 472983e9580Sangelos BEGIN(ACTIONSTRING); /* We're doing conditions-string parsing */ 473983e9580Sangelos first_tok = ACTSTR; 474983e9580Sangelos as->as_result = 0; 475983e9580Sangelos keynote_returnvalue = 0; 476983e9580Sangelos 477983e9580Sangelos switch (knparse()) 478983e9580Sangelos { 479983e9580Sangelos case 1: /* Fall through */ 480983e9580Sangelos keynote_errno = ERROR_SYNTAX; 481983e9580Sangelos case -1: 482983e9580Sangelos as->as_result = 0; 483983e9580Sangelos break; 484983e9580Sangelos 485983e9580Sangelos case 0: 486983e9580Sangelos as->as_result = keynote_returnvalue; 487983e9580Sangelos break; 488983e9580Sangelos } 489983e9580Sangelos 490983e9580Sangelos keynote_env_cleanup(&keynote_temp_list, 1); 491983e9580Sangelos keynote_lex_zap(); 4929186b70cSangelos kn_delete_buffer(keynote_bs); 493983e9580Sangelos 494983e9580Sangelos keynote_used_variable = 0; 495983e9580Sangelos keynote_returnvalue = 0; 496313d0fe7Smmcc keynote_temp_list = NULL; 497313d0fe7Smmcc keynote_init_list = NULL; 498983e9580Sangelos 499983e9580Sangelos if (keynote_errno != 0) 500983e9580Sangelos return -1; 501983e9580Sangelos else 502983e9580Sangelos return RESULT_TRUE; 503983e9580Sangelos } 504983e9580Sangelos 505983e9580Sangelos /* 506983e9580Sangelos * Parse/evaluate a key predicate field. 507bdbb5d20Sangelos * Store keys in key predicate as keylist in as->as_keylist, if second 508983e9580Sangelos * argument is true. 509983e9580Sangelos */ 510983e9580Sangelos int 511983e9580Sangelos keynote_parse_keypred(struct assertion *as, int record) 512983e9580Sangelos { 513983e9580Sangelos YY_BUFFER_STATE keypred_state; 514983e9580Sangelos int p = 0, err; 515983e9580Sangelos 516313d0fe7Smmcc if (as->as_keypred_s == NULL) 517983e9580Sangelos return keynote_current_session->ks_values_num - 1; 518983e9580Sangelos 519983e9580Sangelos if (keynote_lex_init() != RESULT_TRUE) 520983e9580Sangelos return -1; 521983e9580Sangelos 522983e9580Sangelos keynote_used_variable = 0; 523983e9580Sangelos keynote_returnvalue = 0; 524983e9580Sangelos keynote_justrecord = record; /* Just want the list of keys in predicate */ 525983e9580Sangelos keynote_init_list = as->as_env; 526983e9580Sangelos 527983e9580Sangelos keypred_state = kn_scan_bytes(as->as_keypred_s, 528983e9580Sangelos as->as_keypred_e - as->as_keypred_s); 529983e9580Sangelos BEGIN(KEYPREDICATE); 530983e9580Sangelos first_tok = KEYPRE; 531983e9580Sangelos 532983e9580Sangelos err = knparse(); 533983e9580Sangelos if (err != 0) 534983e9580Sangelos if (keynote_errno == 0) 535983e9580Sangelos keynote_errno = ERROR_SYNTAX; 536983e9580Sangelos 5379186b70cSangelos kn_delete_buffer(keypred_state); 538983e9580Sangelos keynote_lex_zap(); 539983e9580Sangelos keynote_cleanup_kth(); 540983e9580Sangelos 541313d0fe7Smmcc keynote_init_list = NULL; 542983e9580Sangelos keynote_justrecord = 0; 543983e9580Sangelos p = keynote_returnvalue; 544983e9580Sangelos keynote_returnvalue = 0; 545983e9580Sangelos 546983e9580Sangelos if (record) 547983e9580Sangelos { 548983e9580Sangelos if (keynote_errno != 0) 549983e9580Sangelos { 550983e9580Sangelos keynote_keylist_free(keynote_keypred_keylist); 551313d0fe7Smmcc keynote_keypred_keylist = NULL; 552983e9580Sangelos return -1; 553983e9580Sangelos } 554983e9580Sangelos else 555983e9580Sangelos { 556983e9580Sangelos /* Mark for re-processing if/when environment changes */ 557983e9580Sangelos if (keynote_used_variable) 558983e9580Sangelos { 559983e9580Sangelos keynote_used_variable = 0; 560983e9580Sangelos as->as_internalflags |= ASSERT_IFLAG_WEIRDLICS; 561983e9580Sangelos } 562983e9580Sangelos 563bdbb5d20Sangelos if (as->as_keylist) 564bdbb5d20Sangelos keynote_keylist_free(as->as_keylist); 565983e9580Sangelos as->as_keylist = keynote_keypred_keylist; 566313d0fe7Smmcc keynote_keypred_keylist = NULL; 567983e9580Sangelos return RESULT_TRUE; 568983e9580Sangelos } 569983e9580Sangelos } 570983e9580Sangelos else 571983e9580Sangelos return p; 572983e9580Sangelos } 573983e9580Sangelos 574983e9580Sangelos /* Evaluate an authorizer or signature field. Return RESULT_TRUE on success. 575983e9580Sangelos * Store key in as->as_authorizer. Second argument is set only for Authorizer 576983e9580Sangelos * field parsing. 577983e9580Sangelos */ 578983e9580Sangelos int 579983e9580Sangelos keynote_evaluate_authorizer(struct assertion *as, int flag) 580983e9580Sangelos { 581983e9580Sangelos YY_BUFFER_STATE authorizer_state; 582983e9580Sangelos int err; 583983e9580Sangelos 584983e9580Sangelos if (keynote_lex_init() != RESULT_TRUE) 585983e9580Sangelos return -1; 586983e9580Sangelos 587983e9580Sangelos keynote_init_list = as->as_env; 588983e9580Sangelos keynote_justrecord = 1; 589983e9580Sangelos keynote_used_variable = 0; 590983e9580Sangelos 591313d0fe7Smmcc if ((flag) && (as->as_authorizer != NULL)) 592983e9580Sangelos { 593983e9580Sangelos keynote_free_key(as->as_authorizer, as->as_signeralgorithm); 594313d0fe7Smmcc as->as_authorizer = NULL; 595983e9580Sangelos } 596983e9580Sangelos 597983e9580Sangelos if (flag) 598983e9580Sangelos authorizer_state = kn_scan_bytes(as->as_authorizer_string_s, 599983e9580Sangelos as->as_authorizer_string_e - 600983e9580Sangelos as->as_authorizer_string_s); 601983e9580Sangelos else 602983e9580Sangelos authorizer_state = kn_scan_bytes(as->as_signature_string_s, 603983e9580Sangelos as->as_signature_string_e - 604983e9580Sangelos as->as_signature_string_s); 605983e9580Sangelos 606983e9580Sangelos BEGIN(SIGNERINIT); 607983e9580Sangelos if (flag) 608983e9580Sangelos first_tok = SIGNERKEY; 609983e9580Sangelos else 610983e9580Sangelos first_tok = SIGNATUREENTRY; 611983e9580Sangelos 612983e9580Sangelos err = knparse(); 613983e9580Sangelos if ((err != 0) && (keynote_errno == 0)) 614983e9580Sangelos keynote_errno = ERROR_SYNTAX; 615983e9580Sangelos 6169186b70cSangelos kn_delete_buffer(authorizer_state); 617983e9580Sangelos keynote_lex_zap(); 618983e9580Sangelos 619983e9580Sangelos keynote_justrecord = 0; 620313d0fe7Smmcc keynote_init_list = NULL; 621983e9580Sangelos keynote_returnvalue = 0; 622983e9580Sangelos 623313d0fe7Smmcc if (keynote_keypred_keylist != NULL) 624983e9580Sangelos { 625983e9580Sangelos if (flag) 626983e9580Sangelos { 627983e9580Sangelos if (keynote_used_variable) 628983e9580Sangelos as->as_internalflags |= ASSERT_IFLAG_WEIRDAUTH; 629983e9580Sangelos 630983e9580Sangelos as->as_authorizer = keynote_keypred_keylist->key_key; 631983e9580Sangelos as->as_signeralgorithm = keynote_keypred_keylist->key_alg; 632983e9580Sangelos } 633983e9580Sangelos else 634983e9580Sangelos { 635983e9580Sangelos if (keynote_used_variable) 636983e9580Sangelos as->as_internalflags |= ASSERT_IFLAG_WEIRDSIG; 637983e9580Sangelos 638983e9580Sangelos as->as_signature = keynote_keypred_keylist->key_key; 639983e9580Sangelos } 640983e9580Sangelos 641313d0fe7Smmcc keynote_keypred_keylist->key_key = NULL; 642983e9580Sangelos keynote_keylist_free(keynote_keypred_keylist); 643313d0fe7Smmcc keynote_keypred_keylist = NULL; 644983e9580Sangelos } 645983e9580Sangelos 646983e9580Sangelos keynote_used_variable = 0; 647983e9580Sangelos 648983e9580Sangelos if (keynote_errno != 0) 649983e9580Sangelos return -1; 650983e9580Sangelos else 651983e9580Sangelos return RESULT_TRUE; 652983e9580Sangelos } 653983e9580Sangelos 654983e9580Sangelos /* 655c5ba4a6fSangelos * Exportable front-end to keynote_get_private_key(). 656c5ba4a6fSangelos */ 657c5ba4a6fSangelos char * 658c5ba4a6fSangelos kn_get_string(char *buf) 659c5ba4a6fSangelos { 660c5ba4a6fSangelos return keynote_get_private_key(buf); 661c5ba4a6fSangelos } 662c5ba4a6fSangelos 663c5ba4a6fSangelos /* 664c5ba4a6fSangelos * Parse a private key -- actually, it can deal with any kind of string. 665983e9580Sangelos */ 666983e9580Sangelos char * 667983e9580Sangelos keynote_get_private_key(char *buf) 668983e9580Sangelos { 669983e9580Sangelos YY_BUFFER_STATE pkey; 670983e9580Sangelos char *s; 671983e9580Sangelos int err; 672983e9580Sangelos 673983e9580Sangelos if (keynote_lex_init() != RESULT_TRUE) 674313d0fe7Smmcc return NULL; 675983e9580Sangelos 676313d0fe7Smmcc keynote_privkey = NULL; 677983e9580Sangelos pkey = kn_scan_bytes(buf, strlen(buf)); 678983e9580Sangelos first_tok = PRIVATEKEY; 679983e9580Sangelos err = knparse(); 680983e9580Sangelos kn_delete_buffer(pkey); 681983e9580Sangelos keynote_lex_zap(); 682983e9580Sangelos 683983e9580Sangelos if (err != 0) 684983e9580Sangelos { 685313d0fe7Smmcc if (keynote_privkey != NULL) 686983e9580Sangelos { 687983e9580Sangelos free(keynote_privkey); 688313d0fe7Smmcc keynote_privkey = NULL; 689983e9580Sangelos } 690983e9580Sangelos 691983e9580Sangelos if (keynote_errno == 0) 692983e9580Sangelos keynote_errno = ERROR_SYNTAX; 693983e9580Sangelos 694313d0fe7Smmcc return NULL; 695983e9580Sangelos } 696983e9580Sangelos 697983e9580Sangelos s = keynote_privkey; 698313d0fe7Smmcc keynote_privkey = NULL; 699983e9580Sangelos return s; 700983e9580Sangelos } 701983e9580Sangelos 702983e9580Sangelos /* 703983e9580Sangelos * Parse Local-Constants and KeyNote-Version fields. 704983e9580Sangelos */ 705983e9580Sangelos struct environment * 706983e9580Sangelos keynote_get_envlist(char *buf, char *bufend, int whichfield) 707983e9580Sangelos { 708313d0fe7Smmcc struct environment *en = NULL; 709983e9580Sangelos YY_BUFFER_STATE localinit_state; 710983e9580Sangelos int err; 711983e9580Sangelos 712983e9580Sangelos if (keynote_lex_init() != RESULT_TRUE) 713313d0fe7Smmcc return NULL; 714983e9580Sangelos 715983e9580Sangelos localinit_state = kn_scan_bytes(buf, bufend - buf); 716983e9580Sangelos if (whichfield == 0) 717983e9580Sangelos { 718983e9580Sangelos BEGIN(LOCALINIT); /* We're doing Local-Constants parsing */ 719983e9580Sangelos first_tok = LOCINI; 720983e9580Sangelos } 721983e9580Sangelos else 722983e9580Sangelos { 723983e9580Sangelos BEGIN(KEYNOTEVERSION); /* KeyNote-Version parsing */ 724983e9580Sangelos first_tok = KNVERSION; 725983e9580Sangelos } 726983e9580Sangelos 727983e9580Sangelos err = knparse(); 728983e9580Sangelos if (err != 0) 729983e9580Sangelos if (keynote_errno == 0) 730983e9580Sangelos keynote_errno = ERROR_SYNTAX; 731983e9580Sangelos 732983e9580Sangelos kn_delete_buffer(localinit_state); 733983e9580Sangelos keynote_lex_zap(); 734983e9580Sangelos 735983e9580Sangelos if (!whichfield) 736983e9580Sangelos { 737983e9580Sangelos if (keynote_errno != 0) 738983e9580Sangelos keynote_env_cleanup(&keynote_init_list, 1); 739983e9580Sangelos else 740983e9580Sangelos en = keynote_init_list; 741983e9580Sangelos 742313d0fe7Smmcc keynote_init_list = NULL; 743983e9580Sangelos } 744983e9580Sangelos 7454812cf71Sangelos /* Avoid compiler (-Wall) warnings. Never reached. */ 7464812cf71Sangelos if (0) 7474812cf71Sangelos { 7484812cf71Sangelos yyunput(0, NULL); 7494812cf71Sangelos } 7504812cf71Sangelos 751983e9580Sangelos return en; 752983e9580Sangelos } 753