Navigation


source: freeDiameter/freeDiameter/fdd.y @ 20:277ec00d793e

Last change on this file since 20:277ec00d793e was 20:277ec00d793e, checked in by Sebastien Decugis <sdecugis@nict.go.jp>, 12 years ago

Backup before typhoon... Progress on server side

File size: 14.3 KB
Line 
1/*********************************************************************************************************
2* Software License Agreement (BSD License)                                                               *
3* Author: Sebastien Decugis <sdecugis@nict.go.jp>                                                        *
4*                                                                                                        *
5* Copyright (c) 2009, 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 "fD.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                fprintf(stderr, "%s:%d.%d-%d.%d : %s\n", 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                fprintf(stderr, "%s:%d.%d-%d : %s\n", conf->cnf_file, ploc->first_line, ploc->first_column, ploc->last_column, s);
68        else
69                fprintf(stderr, "%s:%d.%d : %s\n", conf->cnf_file, ploc->first_line, ploc->first_column, s);
70}
71
72int got_peer_noip = 0;
73int got_peer_noipv6 = 0;
74int got_peer_notcp = 0;
75int got_peer_nosctp = 0;
76
77struct peer_info fddpi;
78
79%}
80
81/* Values returned by lex for token */
82%union {
83        char             *string;       /* The string is allocated by strdup in lex.*/
84        int               integer;      /* Store integer values */
85}
86
87/* In case of error in the lexical analysis */
88%token          LEX_ERROR
89
90%token <string> QSTRING
91%token <integer> INTEGER
92
93%type <string>  extconf
94
95%token          IDENTITY
96%token          REALM
97%token          PORT
98%token          SECPORT
99%token          NOIP
100%token          NOIP6
101%token          NOTCP
102%token          NOSCTP
103%token          PREFERTCP
104%token          OLDTLS
105%token          NOTLS
106%token          SCTPSTREAMS
107%token          LISTENON
108%token          TCTIMER
109%token          TWTIMER
110%token          NORELAY
111%token          LOADEXT
112%token          CONNPEER
113%token          CONNTO
114%token          TLS_CRED
115%token          TLS_CA
116%token          TLS_CRL
117%token          TLS_PRIO
118%token          TLS_DH_BITS
119
120
121/* -------------------------------------- */
122%%
123
124        /* The grammar definition - Sections blocs. */
125conffile:               /* Empty is OK -- for simplicity here, we reject in daemon later */
126                        | conffile identity
127                        | conffile realm
128                        | conffile tctimer
129                        | conffile twtimer
130                        | conffile port
131                        | conffile secport
132                        | conffile sctpstreams
133                        | conffile listenon
134                        | conffile norelay
135                        | conffile noip
136                        | conffile noip6
137                        | conffile notcp
138                        | conffile nosctp
139                        | conffile prefertcp
140                        | conffile oldtls
141                        | conffile loadext
142                        | conffile connpeer
143                        | conffile tls_cred
144                        | conffile tls_ca
145                        | conffile tls_crl
146                        | conffile tls_prio
147                        | conffile tls_dh
148                        | conffile errors
149                        {
150                                yyerror(&yylloc, conf, "An error occurred while parsing the configuration file");
151                                return EINVAL;
152                        }
153                        ;
154
155                        /* Lexical or syntax error */
156errors:                 LEX_ERROR
157                        | error
158                        ;
159
160identity:               IDENTITY '=' QSTRING ';'
161                        {
162                                conf->cnf_diamid = $3;
163                        }
164                        ;
165
166realm:                  REALM '=' QSTRING ';'
167                        {
168                                conf->cnf_diamrlm = $3;
169                        }
170                        ;
171
172tctimer:                TCTIMER '=' INTEGER ';'
173                        {
174                                CHECK_PARAMS_DO( ($3 > 0),
175                                        { yyerror (&yylloc, conf, "Invalid value"); YYERROR; } );
176                                conf->cnf_timer_tc = (unsigned int)$3;
177                        }
178                        ;
179
180twtimer:                TWTIMER '=' INTEGER ';'
181                        {
182                                CHECK_PARAMS_DO( ($3 > 5),
183                                        { yyerror (&yylloc, conf, "Invalid value"); YYERROR; } );
184                                conf->cnf_timer_tw = (unsigned int)$3;
185                        }
186                        ;
187
188port:                   PORT '=' INTEGER ';'
189                        {
190                                CHECK_PARAMS_DO( ($3 > 0) && ($3 < 1<<16),
191                                        { yyerror (&yylloc, conf, "Invalid value"); YYERROR; } );
192                                conf->cnf_port = (uint16_t)$3;
193                        }
194                        ;
195
196secport:                SECPORT '=' INTEGER ';'
197                        {
198                                CHECK_PARAMS_DO( ($3 > 0) && ($3 < 1<<16),
199                                        { yyerror (&yylloc, conf, "Invalid value"); YYERROR; } );
200                                conf->cnf_port_tls = (uint16_t)$3;
201                        }
202                        ;
203
204sctpstreams:            SCTPSTREAMS '=' INTEGER ';'
205                        {
206                                CHECK_PARAMS_DO( ($3 > 0) && ($3 < 1<<16),
207                                        { yyerror (&yylloc, conf, "Invalid value"); YYERROR; } );
208                                conf->cnf_sctp_str = (uint16_t)$3;
209                        }
210                        ;
211
212listenon:               LISTENON '=' QSTRING ';'
213                        {
214                                struct fd_endpoint * ep;
215                                struct addrinfo hints, *ai;
216                                int ret;
217                               
218                                CHECK_MALLOC_DO( ep = malloc(sizeof(struct fd_endpoint)),
219                                        { yyerror (&yylloc, conf, "Out of memory"); YYERROR; } );
220                                memset(ep, 0, sizeof(struct fd_endpoint));
221                                fd_list_init(&ep->chain, NULL);
222                                ep->meta.conf = 1;
223                               
224                                memset(&hints, 0, sizeof(hints));
225                                hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST;
226                                ret = getaddrinfo($3, NULL, &hints, &ai);
227                                if (ret) { yyerror (&yylloc, conf, gai_strerror(ret)); free(ep); YYERROR; }
228                                ASSERT( ai->ai_addrlen <= sizeof(sSS) );
229                                memcpy(&ep->ss, ai->ai_addr, ai->ai_addrlen);
230                                free($3);
231                                freeaddrinfo(ai);
232                                fd_list_insert_before(&conf->cnf_endpoints, &ep->chain);
233                        }
234                        ;
235
236norelay:                NORELAY ';'
237                        {
238                                conf->cnf_flags.no_fwd = 1;
239                        }
240                        ;
241
242noip:                   NOIP ';'
243                        {
244                                if (got_peer_noipv6) {
245                                        yyerror (&yylloc, conf, "No_IP conflicts with a ConnectPeer directive No_IPv6.");
246                                        YYERROR;
247                                }
248                                conf->cnf_flags.no_ip4 = 1;
249                        }
250                        ;
251
252noip6:                  NOIP6 ';'
253                        {
254                                if (got_peer_noip) {
255                                        yyerror (&yylloc, conf, "No_IP conflicts with a ConnectPeer directive No_IP.");
256                                        YYERROR;
257                                }
258                                conf->cnf_flags.no_ip6 = 1;
259                        }
260                        ;
261
262notcp:                  NOTCP ';'
263                        {
264                                #ifdef DISABLE_SCTP
265                                yyerror (&yylloc, conf, "No_TCP cannot be specified for daemon compiled with DISABLE_SCTP option.");
266                                YYERROR;
267                                #endif
268                                if (conf->cnf_flags.no_sctp)
269                                {
270                                        yyerror (&yylloc, conf, "No_TCP conflicts with No_SCTP directive." );
271                                        YYERROR;
272                                }
273                                if (got_peer_nosctp) {
274                                        yyerror (&yylloc, conf, "No_TCP conflicts with a ConnectPeer directive No_SCTP.");
275                                        YYERROR;
276                                }
277                                conf->cnf_flags.no_tcp = 1;
278                        }
279                        ;
280
281nosctp:                 NOSCTP ';'
282                        {
283                                if (conf->cnf_flags.no_tcp)
284                                {
285                                        yyerror (&yylloc, conf, "No_SCTP conflicts with No_TCP directive." );
286                                        YYERROR;
287                                }
288                                if (got_peer_notcp) {
289                                        yyerror (&yylloc, conf, "No_SCTP conflicts with a ConnectPeer directive No_TCP.");
290                                        YYERROR;
291                                }
292                                conf->cnf_flags.no_sctp = 1;
293                        }
294                        ;
295
296prefertcp:              PREFERTCP ';'
297                        {
298                                conf->cnf_flags.pr_tcp = 1;
299                        }
300                        ;
301
302oldtls:                 OLDTLS ';'
303                        {
304                                conf->cnf_flags.tls_alg = 1;
305                        }
306                        ;
307
308loadext:                LOADEXT '=' QSTRING extconf ';'
309                        {
310                                CHECK_FCT_DO( fd_ext_add( $3, $4 ),
311                                        { yyerror (&yylloc, conf, "Error adding extension"); YYERROR; } );
312                        }
313                        ;
314                       
315extconf:                /* empty */
316                        {
317                                $$ = NULL;
318                        }
319                        | ':' QSTRING
320                        {
321                                $$ = $2;
322                        }
323                        ;
324                       
325connpeer:               {
326                                memset(&fddpi, 0, sizeof(fddpi));
327                                fd_list_init( &fddpi.pi_endpoints, NULL );
328                                fd_list_init( &fddpi.pi_apps, NULL );
329                        }
330                        CONNPEER '=' QSTRING peerinfo ';'
331                        {
332                                fddpi.pi_diamid = $4;
333                                CHECK_FCT_DO( fd_peer_add ( &fddpi, conf->cnf_file, NULL, NULL ),
334                                        { yyerror (&yylloc, conf, "Error adding ConnectPeer information"); YYERROR; } );
335                                       
336                                /* Now destroy any content in the structure */
337                                free(fddpi.pi_diamid);
338                                while (!FD_IS_LIST_EMPTY(&fddpi.pi_endpoints)) {
339                                        struct fd_list * li = fddpi.pi_endpoints.next;
340                                        fd_list_unlink(li);
341                                        free(li);
342                                }
343                        }
344                        ;
345                       
346peerinfo:               /* empty */
347                        | '{' peerparams '}'
348                        ;
349                       
350peerparams:             /* empty */
351                        | peerparams NOIP ';'
352                        {
353                                if ((conf->cnf_flags.no_ip6) || (fddpi.pi_flags.pro3 == PI_P3_IP)) {
354                                        yyerror (&yylloc, conf, "No_IP conflicts with a No_IPv6 directive.");
355                                        YYERROR;
356                                }
357                                got_peer_noip++;
358                                fddpi.pi_flags.pro3 = PI_P3_IPv6;
359                        }
360                        | peerparams NOIP6 ';'
361                        {
362                                if ((conf->cnf_flags.no_ip4) || (fddpi.pi_flags.pro3 == PI_P3_IPv6)) {
363                                        yyerror (&yylloc, conf, "No_IPv6 conflicts with a No_IP directive.");
364                                        YYERROR;
365                                }
366                                got_peer_noipv6++;
367                                fddpi.pi_flags.pro3 = PI_P3_IP;
368                        }
369                        | peerparams NOTCP ';'
370                        {
371                                #ifdef DISABLE_SCTP
372                                        yyerror (&yylloc, conf, "No_TCP cannot be specified in daemon compiled with DISABLE_SCTP option.");
373                                        YYERROR;
374                                #endif
375                                if ((conf->cnf_flags.no_sctp) || (fddpi.pi_flags.pro4 == PI_P4_TCP)) {
376                                        yyerror (&yylloc, conf, "No_TCP conflicts with a No_SCTP directive.");
377                                        YYERROR;
378                                }
379                                got_peer_notcp++;
380                                fddpi.pi_flags.pro4 = PI_P4_SCTP;
381                        }
382                        | peerparams NOSCTP ';'
383                        {
384                                if ((conf->cnf_flags.no_tcp) || (fddpi.pi_flags.pro4 == PI_P4_SCTP)) {
385                                        yyerror (&yylloc, conf, "No_SCTP conflicts with a No_TCP directive.");
386                                        YYERROR;
387                                }
388                                got_peer_nosctp++;
389                                fddpi.pi_flags.pro4 = PI_P4_TCP;
390                        }
391                        | peerparams PREFERTCP ';'
392                        {
393                                fddpi.pi_flags.alg = PI_ALGPREF_TCP;
394                        }
395                        | peerparams OLDTLS ';'
396                        {
397                                if (fddpi.pi_flags.sec == PI_SEC_NONE) {
398                                        yyerror (&yylloc, conf, "ConnectPeer: TLS_old_method conflicts with No_TLS.");
399                                        YYERROR;
400                                }
401                                fddpi.pi_flags.sec = PI_SEC_TLS_OLD;
402                        }
403                        | peerparams NOTLS ';'
404                        {
405                                if (fddpi.pi_flags.sec == PI_SEC_TLS_OLD) {
406                                        yyerror (&yylloc, conf, "ConnectPeer: No_TLS conflicts with TLS_old_method.");
407                                        YYERROR;
408                                }
409                                fddpi.pi_flags.sec = PI_SEC_NONE;
410                        }
411                        | peerparams PORT '=' INTEGER ';'
412                        {
413                                CHECK_PARAMS_DO( ($4 > 0) && ($4 < 1<<16),
414                                        { yyerror (&yylloc, conf, "Invalid value"); YYERROR; } );
415                                fddpi.pi_port = (uint16_t)$4;
416                        }
417                        | peerparams SCTPSTREAMS '=' INTEGER ';'
418                        {
419                                CHECK_PARAMS_DO( ($4 > 0) && ($4 < 1<<16),
420                                        { yyerror (&yylloc, conf, "Invalid value"); YYERROR; } );
421                                fddpi.pi_streams = (uint16_t)$4;
422                        }
423                        | peerparams TCTIMER '=' INTEGER ';'
424                        {
425                                fddpi.pi_tctimer = $4;
426                        }
427                        | peerparams TWTIMER '=' INTEGER ';'
428                        {
429                                fddpi.pi_twtimer = $4;
430                        }
431                        | peerparams CONNTO '=' QSTRING ';'
432                        {
433                                struct fd_endpoint * ep;
434                                struct addrinfo hints, *ai;
435                                int ret;
436                               
437                                CHECK_MALLOC_DO( ep = malloc(sizeof(struct fd_endpoint)),
438                                        { yyerror (&yylloc, conf, "Out of memory"); YYERROR; } );
439                                memset(ep, 0, sizeof(struct fd_endpoint));
440                                fd_list_init(&ep->chain, NULL);
441                                ep->meta.conf = 1;
442                                memset(&hints, 0, sizeof(hints));
443                                hints.ai_flags = AI_ADDRCONFIG | AI_NUMERICHOST;
444                                ret = getaddrinfo($4, NULL, &hints, &ai);
445                                if (ret == EAI_NONAME) {
446                                        /* The name was maybe not numeric, try again */
447                                        ep->meta.disc = 1;
448                                        hints.ai_flags &= ~ AI_NUMERICHOST;
449                                        ret = getaddrinfo($4, NULL, &hints, &ai);
450                                }
451                                if (ret) { yyerror (&yylloc, conf, gai_strerror(ret)); free(ep); YYERROR; }
452                               
453                                memcpy(&ep->ss, ai->ai_addr, ai->ai_addrlen);
454                                free($4);
455                                freeaddrinfo(ai);
456                                fd_list_insert_before(&fddpi.pi_endpoints, &ep->chain);
457                        }
458                        ;
459
460tls_cred:               TLS_CRED '=' QSTRING ',' QSTRING ';'
461                        {
462                                conf->cnf_sec_data.cert_file = $3;
463                                conf->cnf_sec_data.key_file = $5;
464                               
465                                CHECK_GNUTLS_DO( gnutls_certificate_set_x509_key_file(
466                                                        conf->cnf_sec_data.credentials,
467                                                        conf->cnf_sec_data.cert_file,
468                                                        conf->cnf_sec_data.key_file,
469                                                        GNUTLS_X509_FMT_PEM),
470                                                { yyerror (&yylloc, conf, "Error opening certificate or private key file."); YYERROR; } );
471                        }
472                        ;
473
474tls_ca:                 TLS_CA '=' QSTRING ';'
475                        {
476                                conf->cnf_sec_data.ca_file = $3;
477                                CHECK_GNUTLS_DO( gnutls_certificate_set_x509_trust_file(
478                                                        conf->cnf_sec_data.credentials,
479                                                        conf->cnf_sec_data.ca_file,
480                                                        GNUTLS_X509_FMT_PEM),
481                                                { yyerror (&yylloc, conf, "Error setting CA parameters."); YYERROR; } );
482                        }
483                        ;
484                       
485tls_crl:                TLS_CRL '=' QSTRING ';'
486                        {
487                                conf->cnf_sec_data.crl_file = $3;
488                                CHECK_GNUTLS_DO( gnutls_certificate_set_x509_crl_file(
489                                                        conf->cnf_sec_data.credentials,
490                                                        conf->cnf_sec_data.ca_file,
491                                                        GNUTLS_X509_FMT_PEM),
492                                                { yyerror (&yylloc, conf, "Error setting CRL parameters."); YYERROR; } );
493                        }
494                        ;
495                       
496tls_prio:               TLS_PRIO '=' QSTRING ';'
497                        {
498                                const char * err_pos = NULL;
499                                conf->cnf_sec_data.prio_string = $3;
500                                CHECK_GNUTLS_DO( gnutls_priority_init(
501                                                        &conf->cnf_sec_data.prio_cache,
502                                                        conf->cnf_sec_data.prio_string,
503                                                        &err_pos),
504                                                { yyerror (&yylloc, conf, "Error setting Priority parameter.");
505                                                  fprintf(stderr, "Error at position : %s\n", err_pos);
506                                                  YYERROR; } );
507                        }
508                        ;
509                       
510tls_dh:                 TLS_DH_BITS '=' INTEGER ';'
511                        {
512                                conf->cnf_sec_data.dh_bits = $3;
513                                TRACE_DEBUG(FULL, "Generating DH parameters...");
514                                CHECK_GNUTLS_DO( gnutls_dh_params_generate2(
515                                                        conf->cnf_sec_data.dh_cache,
516                                                        conf->cnf_sec_data.dh_bits),
517                                                { yyerror (&yylloc, conf, "Error setting DH Bits parameters.");
518                                                 YYERROR; } );
519                                TRACE_DEBUG(FULL, "DH parameters generated.");
520                        }
521                        ;
Note: See TracBrowser for help on using the repository browser.