blob: 07707c99135fe7734b6373f427747db34d7e2f19 [file] [log] [blame]
Brian Waters13d96012017-12-08 16:53:31 -06001/*********************************************************************************************************
2* Software License Agreement (BSD License) *
3* Author: Sebastien Decugis <sdecugis@freediameter.net> *
4* *
5* Copyright (c) 2015, WIDE Project and NICT *
6* All rights reserved. *
7* *
8* Redistribution and use of this software in source and binary forms, with or without modification, are *
9* permitted provided that the following conditions are met: *
10* *
11* * Redistributions of source code must retain the above *
12* copyright notice, this list of conditions and the *
13* following disclaimer. *
14* *
15* * Redistributions in binary form must reproduce the above *
16* copyright notice, this list of conditions and the *
17* following disclaimer in the documentation and/or other *
18* materials provided with the distribution. *
19* *
20* * Neither the name of the WIDE Project or NICT nor the *
21* names of its contributors may be used to endorse or *
22* promote products derived from this software without *
23* specific prior written permission of WIDE Project and *
24* NICT. *
25* *
26* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED *
27* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
28* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR *
29* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT *
30* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS *
31* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR *
32* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF *
33* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
34*********************************************************************************************************/
35
36/* Yacc configuration parser.
37 *
38 * This file defines the grammar of the configuration file.
39 * Note that each extension has a separate independant configuration file.
40 *
41 * Note : This module is NOT thread-safe. All processing must be done from one thread only.
42 */
43
44/* For development only : */
45%debug
46%error-verbose
47
48%parse-param {struct fd_config * conf}
49
50/* Keep track of location */
51%locations
52%pure-parser
53
54%{
55#include "fdcore-internal.h"
56#include "fdd.tab.h" /* bug : bison does not define the YYLTYPE before including this bloc, so... */
57
58/* The Lex parser prototype */
59int fddlex(YYSTYPE *lvalp, YYLTYPE *llocp);
60
61/* Function to report error */
62void yyerror (YYLTYPE *ploc, struct fd_config * conf, char const *s)
63{
64 if (ploc->first_line != ploc->last_line) {
65 TRACE_ERROR("%s:%d.%d-%d.%d : %s", conf->cnf_file, ploc->first_line, ploc->first_column, ploc->last_line, ploc->last_column, s);
66 } else if (ploc->first_column != ploc->last_column) {
67 TRACE_ERROR("%s:%d.%d-%d : %s", conf->cnf_file, ploc->first_line, ploc->first_column, ploc->last_column, s);
68 } else {
69 TRACE_ERROR("%s:%d.%d : %s", conf->cnf_file, ploc->first_line, ploc->first_column, s);
70 }
71}
72
73int got_peer_noip = 0;
74int got_peer_noipv6 = 0;
75int got_peer_notcp = 0;
76int got_peer_nosctp = 0;
77
78struct peer_info fddpi;
79
80%}
81
82/* Values returned by lex for token */
83%union {
84 char *string; /* The string is allocated by strdup in lex.*/
85 int integer; /* Store integer values */
86}
87
88/* In case of error in the lexical analysis */
89%token LEX_ERROR
90
91%token <string> QSTRING
92%token <integer> INTEGER
93
94%type <string> extconf
95
96%token IDENTITY
97%token REALM
98%token PORT
99%token SECPORT
100%token SEC3436
101%token NOIP
102%token NOIP6
103%token NOTCP
104%token NOSCTP
105%token PREFERTCP
106%token OLDTLS
107%token NOTLS
108%token SCTPSTREAMS
109%token APPSERVTHREADS
110%token LISTENON
111%token THRPERSRV
112%token TCTIMER
113%token TWTIMER
114%token NORELAY
115%token LOADEXT
116%token CONNPEER
117%token CONNTO
118%token TLS_CRED
119%token TLS_CA
120%token TLS_CRL
121%token TLS_PRIO
122%token TLS_DH_BITS
123%token TLS_DH_FILE
124
125
126/* -------------------------------------- */
127%%
128
129 /* The grammar definition - Sections blocs. */
130conffile: /* Empty is OK -- for simplicity here, we reject in daemon later */
131 | conffile identity
132 | conffile realm
133 | conffile tctimer
134 | conffile twtimer
135 | conffile port
136 | conffile secport
137 | conffile sec3436
138 | conffile sctpstreams
139 | conffile listenon
140 | conffile thrpersrv
141 | conffile norelay
142 | conffile appservthreads
143 | conffile noip
144 | conffile noip6
145 | conffile notcp
146 | conffile nosctp
147 | conffile prefertcp
148 | conffile oldtls
149 | conffile loadext
150 | conffile connpeer
151 | conffile tls_cred
152 | conffile tls_ca
153 | conffile tls_crl
154 | conffile tls_prio
155 | conffile tls_dh
156 | conffile errors
157 {
158 yyerror(&yylloc, conf, "An error occurred while parsing the configuration file");
159 return EINVAL;
160 }
161 ;
162
163 /* Lexical or syntax error */
164errors: LEX_ERROR
165 | error
166 ;
167
168identity: IDENTITY '=' QSTRING ';'
169 {
170 conf->cnf_diamid = $3;
171 }
172 ;
173
174realm: REALM '=' QSTRING ';'
175 {
176 conf->cnf_diamrlm = $3;
177 }
178 ;
179
180tctimer: TCTIMER '=' INTEGER ';'
181 {
182 CHECK_PARAMS_DO( ($3 > 0),
183 { yyerror (&yylloc, conf, "Invalid value"); YYERROR; } );
184 conf->cnf_timer_tc = (unsigned int)$3;
185 }
186 ;
187
188twtimer: TWTIMER '=' INTEGER ';'
189 {
190 CHECK_PARAMS_DO( ($3 > 5),
191 { yyerror (&yylloc, conf, "Invalid value"); YYERROR; } );
192 conf->cnf_timer_tw = (unsigned int)$3;
193 }
194 ;
195
196port: PORT '=' INTEGER ';'
197 {
198 CHECK_PARAMS_DO( ($3 >= 0) && ($3 < 1<<16),
199 { yyerror (&yylloc, conf, "Invalid value"); YYERROR; } );
200 conf->cnf_port = (uint16_t)$3;
201 }
202 ;
203
204secport: SECPORT '=' INTEGER ';'
205 {
206 CHECK_PARAMS_DO( ($3 >= 0) && ($3 < 1<<16),
207 { yyerror (&yylloc, conf, "Invalid value"); YYERROR; } );
208 conf->cnf_port_tls = (uint16_t)$3;
209 }
210 ;
211
212sec3436: SEC3436 '=' INTEGER ';'
213 {
214 CHECK_PARAMS_DO( ($3 >= 0) && ($3 < 1<<16),
215 { yyerror (&yylloc, conf, "Invalid value"); YYERROR; } );
216 conf->cnf_port_3436 = (uint16_t)$3;
217 }
218 ;
219
220sctpstreams: SCTPSTREAMS '=' INTEGER ';'
221 {
222 CHECK_PARAMS_DO( ($3 > 0) && ($3 < 1<<16),
223 { yyerror (&yylloc, conf, "Invalid value"); YYERROR; } );
224 conf->cnf_sctp_str = (uint16_t)$3;
225 }
226 ;
227
228listenon: LISTENON '=' QSTRING ';'
229 {
230 struct addrinfo hints, *ai;
231 int ret;
232
233 memset(&hints, 0, sizeof(hints));
234 hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST;
235 ret = getaddrinfo($3, NULL, &hints, &ai);
236 if (ret) { yyerror (&yylloc, conf, gai_strerror(ret)); YYERROR; }
237 CHECK_FCT_DO( fd_ep_add_merge( &conf->cnf_endpoints, ai->ai_addr, ai->ai_addrlen, EP_FL_CONF ), YYERROR );
238 freeaddrinfo(ai);
239 free($3);
240 }
241 ;
242
243thrpersrv: THRPERSRV '=' INTEGER ';'
244 {
245 CHECK_PARAMS_DO( ($3 > 0),
246 { yyerror (&yylloc, conf, "Invalid value"); YYERROR; } );
247 conf->cnf_thr_srv = $3;
248 }
249 ;
250
251norelay: NORELAY ';'
252 {
253 conf->cnf_flags.no_fwd = 1;
254 }
255 ;
256
257appservthreads: APPSERVTHREADS '=' INTEGER ';'
258 {
259 CHECK_PARAMS_DO( ($3 > 0) && ($3 < 256),
260 { yyerror (&yylloc, conf, "Invalid value"); YYERROR; } );
261 conf->cnf_dispthr = (uint16_t)$3;
262 }
263 ;
264
265noip: NOIP ';'
266 {
267 if (got_peer_noipv6) {
268 yyerror (&yylloc, conf, "No_IP conflicts with a ConnectPeer directive No_IPv6.");
269 YYERROR;
270 }
271 conf->cnf_flags.no_ip4 = 1;
272 }
273 ;
274
275noip6: NOIP6 ';'
276 {
277 if (got_peer_noip) {
278 yyerror (&yylloc, conf, "No_IP conflicts with a ConnectPeer directive No_IP.");
279 YYERROR;
280 }
281 conf->cnf_flags.no_ip6 = 1;
282 }
283 ;
284
285notcp: NOTCP ';'
286 {
287 #ifdef DISABLE_SCTP
288 yyerror (&yylloc, conf, "No_TCP cannot be specified for daemon compiled with DISABLE_SCTP option.");
289 YYERROR;
290 #endif
291 if (conf->cnf_flags.no_sctp)
292 {
293 yyerror (&yylloc, conf, "No_TCP conflicts with No_SCTP directive." );
294 YYERROR;
295 }
296 if (got_peer_nosctp) {
297 yyerror (&yylloc, conf, "No_TCP conflicts with a ConnectPeer directive No_SCTP.");
298 YYERROR;
299 }
300 conf->cnf_flags.no_tcp = 1;
301 }
302 ;
303
304nosctp: NOSCTP ';'
305 {
306 if (conf->cnf_flags.no_tcp)
307 {
308 yyerror (&yylloc, conf, "No_SCTP conflicts with No_TCP directive." );
309 YYERROR;
310 }
311 if (got_peer_notcp) {
312 yyerror (&yylloc, conf, "No_SCTP conflicts with a ConnectPeer directive No_TCP.");
313 YYERROR;
314 }
315 conf->cnf_flags.no_sctp = 1;
316 }
317 ;
318
319prefertcp: PREFERTCP ';'
320 {
321 conf->cnf_flags.pr_tcp = 1;
322 }
323 ;
324
325oldtls: OLDTLS ';'
326 {
327 conf->cnf_flags.tls_alg = 1;
328 }
329 ;
330
331loadext: LOADEXT '=' QSTRING extconf ';'
332 {
333 char * fname;
334 char * cfname;
335 FILE * fd;
336
337 /* Try and open the extension file */
338 fname = $3;
339 fd = fopen(fname, "r");
340 if ((fd == NULL) && (*fname != '/')) {
341 char * bkp = fname;
342 CHECK_MALLOC_DO( fname = malloc( strlen(bkp) + strlen(DEFAULT_EXTENSIONS_PATH) + 2 ),
343 { yyerror (&yylloc, conf, "Not enough memory"); YYERROR; } );
344 sprintf(fname, DEFAULT_EXTENSIONS_PATH "/%s", bkp);
345 fd = fopen(fname, "r");
346 if (fd == NULL) {
347 free(fname);
348 fname = bkp;
349 } else {
350 free(bkp);
351 }
352 }
353 if (fd != NULL) {
354 fclose(fd);
355 } /* otherwise, LD_LIBRARY_PATH will be tested by dl_open.
356 This should not give any security issue, otherwise we can add an "else fail" here. */
357
358 /* Try and open the configuration file (optional) */
359 cfname = $4;
360 if (cfname) {
361 fd = fopen(cfname, "r");
362 if ((fd == NULL) && (*cfname != '/')) {
363 char * test;
364 CHECK_MALLOC_DO( test = malloc( strlen(cfname) + strlen(DEFAULT_CONF_PATH) + 2 ),
365 { yyerror (&yylloc, conf, "Not enough memory"); YYERROR; } );
366 sprintf(test, DEFAULT_CONF_PATH "/%s", cfname);
367 fd = fopen(test, "r");
368 if (fd) {
369 free(cfname);
370 cfname=test;
371 } else {
372 /* This is not an error, we allow an extension to wait for something else than a real conf file. */
373 free(test);
374 }
375 }
376 if (fd)
377 fclose(fd);
378 }
379
380 CHECK_FCT_DO( fd_ext_add( fname, cfname ),
381 { yyerror (&yylloc, conf, "Error adding extension"); YYERROR; } );
382 }
383 ;
384
385extconf: /* empty */
386 {
387 $$ = NULL;
388 }
389 | ':' QSTRING
390 {
391 $$ = $2;
392 }
393 ;
394
395connpeer: {
396 memset(&fddpi, 0, sizeof(fddpi));
397 fddpi.config.pic_flags.persist = PI_PRST_ALWAYS;
398 fd_list_init( &fddpi.pi_endpoints, NULL );
399 }
400 CONNPEER '=' QSTRING peerinfo ';'
401 {
402 fddpi.pi_diamid = $4;
403 CHECK_FCT_DO( fd_peer_add ( &fddpi, conf->cnf_file, NULL, NULL ),
404 { yyerror (&yylloc, conf, "Error adding ConnectPeer information"); YYERROR; } );
405
406 /* Now destroy any content in the structure */
407 free(fddpi.pi_diamid);
408 free(fddpi.config.pic_realm);
409 free(fddpi.config.pic_priority);
410 while (!FD_IS_LIST_EMPTY(&fddpi.pi_endpoints)) {
411 struct fd_list * li = fddpi.pi_endpoints.next;
412 fd_list_unlink(li);
413 free(li);
414 }
415 }
416 ;
417
418peerinfo: /* empty */
419 | '{' peerparams '}'
420 ;
421
422peerparams: /* empty */
423 | peerparams NOIP ';'
424 {
425 if ((conf->cnf_flags.no_ip6) || (fddpi.config.pic_flags.pro3 == PI_P3_IP)) {
426 yyerror (&yylloc, conf, "No_IP conflicts with a No_IPv6 directive.");
427 YYERROR;
428 }
429 got_peer_noip++;
430 fddpi.config.pic_flags.pro3 = PI_P3_IPv6;
431 }
432 | peerparams NOIP6 ';'
433 {
434 if ((conf->cnf_flags.no_ip4) || (fddpi.config.pic_flags.pro3 == PI_P3_IPv6)) {
435 yyerror (&yylloc, conf, "No_IPv6 conflicts with a No_IP directive.");
436 YYERROR;
437 }
438 got_peer_noipv6++;
439 fddpi.config.pic_flags.pro3 = PI_P3_IP;
440 }
441 | peerparams NOTCP ';'
442 {
443 #ifdef DISABLE_SCTP
444 yyerror (&yylloc, conf, "No_TCP cannot be specified in daemon compiled with DISABLE_SCTP option.");
445 YYERROR;
446 #endif
447 if ((conf->cnf_flags.no_sctp) || (fddpi.config.pic_flags.pro4 == PI_P4_TCP)) {
448 yyerror (&yylloc, conf, "No_TCP conflicts with a No_SCTP directive.");
449 YYERROR;
450 }
451 got_peer_notcp++;
452 fddpi.config.pic_flags.pro4 = PI_P4_SCTP;
453 }
454 | peerparams NOSCTP ';'
455 {
456 if ((conf->cnf_flags.no_tcp) || (fddpi.config.pic_flags.pro4 == PI_P4_SCTP)) {
457 yyerror (&yylloc, conf, "No_SCTP conflicts with a No_TCP directive.");
458 YYERROR;
459 }
460 got_peer_nosctp++;
461 fddpi.config.pic_flags.pro4 = PI_P4_TCP;
462 }
463 | peerparams PREFERTCP ';'
464 {
465 fddpi.config.pic_flags.alg = PI_ALGPREF_TCP;
466 }
467 | peerparams OLDTLS ';'
468 {
469 fddpi.config.pic_flags.sec |= PI_SEC_TLS_OLD;
470 }
471 | peerparams NOTLS ';'
472 {
473 fddpi.config.pic_flags.sec |= PI_SEC_NONE;
474 }
475 | peerparams SEC3436 ';'
476 {
477 fddpi.config.pic_flags.sctpsec |= PI_SCTPSEC_3436;
478 }
479 | peerparams REALM '=' QSTRING ';'
480 {
481 fddpi.config.pic_realm = $4;
482 }
483 | peerparams PORT '=' INTEGER ';'
484 {
485 CHECK_PARAMS_DO( ($4 > 0) && ($4 < 1<<16),
486 { yyerror (&yylloc, conf, "Invalid port value"); YYERROR; } );
487 fddpi.config.pic_port = (uint16_t)$4;
488 }
489 | peerparams TCTIMER '=' INTEGER ';'
490 {
491 fddpi.config.pic_tctimer = $4;
492 }
493 | peerparams TWTIMER '=' INTEGER ';'
494 {
495 fddpi.config.pic_twtimer = $4;
496 }
497 | peerparams TLS_PRIO '=' QSTRING ';'
498 {
499 fddpi.config.pic_priority = $4;
500 }
501 | peerparams CONNTO '=' QSTRING ';'
502 {
503 struct addrinfo hints, *ai;
504 int ret;
505 int disc = 0;
506
507 memset(&hints, 0, sizeof(hints));
508 hints.ai_flags = AI_ADDRCONFIG | AI_NUMERICHOST;
509 ret = getaddrinfo($4, NULL, &hints, &ai);
510 if (ret == EAI_NONAME) {
511 /* The name was maybe not numeric, try again */
512 disc = EP_FL_DISC;
513 hints.ai_flags &= ~ AI_NUMERICHOST;
514 ret = getaddrinfo($4, NULL, &hints, &ai);
515 }
516 if (ret) { yyerror (&yylloc, conf, gai_strerror(ret)); YYERROR; }
517
518 CHECK_FCT_DO( fd_ep_add_merge( &fddpi.pi_endpoints, ai->ai_addr, ai->ai_addrlen, EP_FL_CONF | (disc ?: EP_ACCEPTALL) ), YYERROR );
519 free($4);
520 freeaddrinfo(ai);
521 }
522 ;
523
524tls_cred: TLS_CRED '=' QSTRING ',' QSTRING ';'
525 {
526 FILE * fd;
527 fd = fopen($3, "r");
528 if (fd == NULL) {
529 int ret = errno;
530 TRACE_ERROR("Unable to open certificate file %s for reading: %s", $3, strerror(ret));
531 yyerror (&yylloc, conf, "Error on file name");
532 YYERROR;
533 }
534 fclose(fd);
535 fd = fopen($5, "r");
536 if (fd == NULL) {
537 int ret = errno;
538 TRACE_ERROR("Unable to open private key file %s for reading: %s", $5, strerror(ret));
539 yyerror (&yylloc, conf, "Error on file name");
540 YYERROR;
541 }
542 fclose(fd);
543 conf->cnf_sec_data.cert_file = $3;
544 conf->cnf_sec_data.key_file = $5;
545
546 CHECK_GNUTLS_DO( gnutls_certificate_set_x509_key_file(
547 conf->cnf_sec_data.credentials,
548 conf->cnf_sec_data.cert_file,
549 conf->cnf_sec_data.key_file,
550 GNUTLS_X509_FMT_PEM),
551 { yyerror (&yylloc, conf, "Error opening certificate or private key file."); YYERROR; } );
552 }
553 ;
554
555tls_ca: TLS_CA '=' QSTRING ';'
556 {
557 FILE * fd;
558 fd = fopen($3, "rb");
559 if (fd == NULL) {
560 int ret = errno;
561 TRACE_ERROR("Unable to open CA file %s for reading: %s", $3, strerror(ret));
562 yyerror (&yylloc, conf, "Error on file name");
563 YYERROR;
564 }
565 #ifdef GNUTLS_VERSION_300
566 {
567 /* We import these CA in the trust list */
568 gnutls_x509_crt_t * calist;
569 unsigned int cacount;
570 gnutls_datum_t cafile;
571
572 CHECK_FCT_DO( fd_conf_stream_to_gnutls_datum(fd, &cafile),
573 { yyerror (&yylloc, conf, "Error reading CA file."); YYERROR; } );
574
575 CHECK_GNUTLS_DO( gnutls_x509_crt_list_import2(&calist, &cacount, &cafile, GNUTLS_X509_FMT_PEM,
576 GNUTLS_X509_CRT_LIST_FAIL_IF_UNSORTED),
577 { yyerror (&yylloc, conf, "Error importing CA file."); YYERROR; } );
578 free(cafile.data);
579
580 CHECK_GNUTLS_DO( gnutls_x509_trust_list_add_cas (fd_g_config->cnf_sec_data.trustlist, calist, cacount, 0),
581 { yyerror (&yylloc, conf, "Error saving CA in trust list."); YYERROR; } );
582 }
583 #endif /* GNUTLS_VERSION_300 */
584 fclose(fd);
585 conf->cnf_sec_data.ca_file = $3;
586 CHECK_GNUTLS_DO( conf->cnf_sec_data.ca_file_nr += gnutls_certificate_set_x509_trust_file(
587 conf->cnf_sec_data.credentials,
588 conf->cnf_sec_data.ca_file,
589 GNUTLS_X509_FMT_PEM),
590 { yyerror (&yylloc, conf, "Error setting CA parameters."); YYERROR; } );
591
592 }
593 ;
594
595tls_crl: TLS_CRL '=' QSTRING ';'
596 {
597 FILE * fd;
598 fd = fopen($3, "rb");
599 if (fd == NULL) {
600 int ret = errno;
601 TRACE_ERROR("Unable to open CRL file %s for reading: %s", $3, strerror(ret));
602 yyerror (&yylloc, conf, "Error on file name");
603 YYERROR;
604 }
605 #ifdef GNUTLS_VERSION_300
606 {
607 /* We import these CRL in the trust list */
608 gnutls_x509_crl_t * crllist;
609 unsigned int crlcount;
610 gnutls_datum_t crlfile;
611
612 CHECK_FCT_DO( fd_conf_stream_to_gnutls_datum(fd, &crlfile),
613 { yyerror (&yylloc, conf, "Error reading CRL file."); YYERROR; } );
614
615 CHECK_GNUTLS_DO( gnutls_x509_crl_list_import2(&crllist, &crlcount, &crlfile, GNUTLS_X509_FMT_PEM, 0),
616 { yyerror (&yylloc, conf, "Error importing CRL file."); YYERROR; } );
617 free(crlfile.data);
618
619 CHECK_GNUTLS_DO( gnutls_x509_trust_list_add_crls (fd_g_config->cnf_sec_data.trustlist, crllist, crlcount,
620 GNUTLS_TL_VERIFY_CRL,
621 0),
622 { yyerror (&yylloc, conf, "Error importing CRL in trust list."); YYERROR; } );
623 }
624 #endif /* GNUTLS_VERSION_300 */
625 fclose(fd);
626 conf->cnf_sec_data.crl_file = $3;
627 CHECK_GNUTLS_DO( gnutls_certificate_set_x509_crl_file(
628 conf->cnf_sec_data.credentials,
629 conf->cnf_sec_data.crl_file,
630 GNUTLS_X509_FMT_PEM),
631 { yyerror (&yylloc, conf, "Error setting CRL parameters."); YYERROR; } );
632 }
633 ;
634
635tls_prio: TLS_PRIO '=' QSTRING ';'
636 {
637 const char * err_pos = NULL;
638 conf->cnf_sec_data.prio_string = $3;
639 CHECK_GNUTLS_DO( gnutls_priority_init(
640 &conf->cnf_sec_data.prio_cache,
641 conf->cnf_sec_data.prio_string,
642 &err_pos),
643 { yyerror (&yylloc, conf, "Error setting Priority parameter.");
644 TRACE_ERROR("Error at position : %s", err_pos);
645 YYERROR; } );
646 }
647 ;
648
649tls_dh: TLS_DH_BITS '=' INTEGER ';'
650 {
651 conf->cnf_sec_data.dh_bits = $3;
652 }
653 | TLS_DH_FILE '=' QSTRING ';'
654 {
655 FILE * fd;
656 free(conf->cnf_sec_data.dh_file);
657 conf->cnf_sec_data.dh_file = $3;
658 fd = fopen($3, "r");
659 if (fd == NULL) {
660 int ret = errno;
661 TRACE_ERROR("Unable to open DH file %s for reading: %s", $3, strerror(ret));
662 yyerror (&yylloc, conf, "Error on file name");
663 YYERROR;
664 }
665 fclose(fd);
666 }
667 ;