ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/branches/8.1.x/src/conf_parser.y
Revision: 1751
Committed: Wed Jan 16 18:30:52 2013 UTC (11 years, 3 months ago) by michael
Original Path: ircd-hybrid/trunk/src/conf_parser.y
File size: 72523 byte(s)
Log Message:
- Forward-port -r1750 [IMPORTANT: nick and topic lengths are now configurable
  via ircd.conf. A max_nick_length, as well as a max_topic_length configuration
  option can now be found in the serverinfo{} block]
- OpenSSL 0.9.8s and higher is now required in order to enable ssl support

File Contents

# Content
1 /*
2 * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd).
3 * conf_parser.y: Parses the ircd configuration file.
4 *
5 * Copyright (C) 2005 by the past and present ircd coders, and others.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
20 * USA
21 *
22 * $Id$
23 */
24
25 %{
26
27 #define YY_NO_UNPUT
28 #include <sys/types.h>
29 #include <string.h>
30
31 #include "config.h"
32 #include "stdinc.h"
33 #include "ircd.h"
34 #include "list.h"
35 #include "conf.h"
36 #include "conf_class.h"
37 #include "event.h"
38 #include "log.h"
39 #include "client.h" /* for UMODE_ALL only */
40 #include "irc_string.h"
41 #include "sprintf_irc.h"
42 #include "memory.h"
43 #include "modules.h"
44 #include "s_serv.h"
45 #include "hostmask.h"
46 #include "send.h"
47 #include "listener.h"
48 #include "resv.h"
49 #include "numeric.h"
50 #include "s_user.h"
51
52 #ifdef HAVE_LIBCRYPTO
53 #include <openssl/rsa.h>
54 #include <openssl/bio.h>
55 #include <openssl/pem.h>
56 #include <openssl/dh.h>
57 #endif
58
59 int yylex(void);
60
61 static struct
62 {
63 struct {
64 dlink_list list;
65 } mask,
66 leaf,
67 hub;
68
69 struct {
70 char buf[IRCD_BUFSIZE];
71 } name,
72 user,
73 host,
74 addr,
75 bind,
76 file,
77 ciph,
78 rpass,
79 spass,
80 class;
81
82 struct {
83 unsigned int value;
84 } flags,
85 modes,
86 size,
87 type,
88 port,
89 aftype,
90 ping_freq,
91 max_perip,
92 con_freq,
93 max_total,
94 max_global,
95 max_local,
96 max_ident,
97 max_sendq,
98 max_recvq,
99 cidr_bitlen_ipv4,
100 cidr_bitlen_ipv6,
101 number_per_cidr;
102 } block_state;
103
104 static void
105 reset_block_state(void)
106 {
107 dlink_node *ptr = NULL, *ptr_next = NULL;
108
109 DLINK_FOREACH_SAFE(ptr, ptr_next, block_state.mask.list.head)
110 {
111 MyFree(ptr->data);
112 dlinkDelete(ptr, &block_state.mask.list);
113 free_dlink_node(ptr);
114 }
115
116 DLINK_FOREACH_SAFE(ptr, ptr_next, block_state.leaf.list.head)
117 {
118 MyFree(ptr->data);
119 dlinkDelete(ptr, &block_state.leaf.list);
120 free_dlink_node(ptr);
121 }
122
123 DLINK_FOREACH_SAFE(ptr, ptr_next, block_state.hub.list.head)
124 {
125 MyFree(ptr->data);
126 dlinkDelete(ptr, &block_state.hub.list);
127 free_dlink_node(ptr);
128 }
129
130 memset(&block_state, 0, sizeof(block_state));
131 }
132
133 %}
134
135 %union {
136 int number;
137 char *string;
138 }
139
140 %token ACCEPT_PASSWORD
141 %token ADMIN
142 %token AFTYPE
143 %token ANTI_NICK_FLOOD
144 %token ANTI_SPAM_EXIT_MESSAGE_TIME
145 %token AUTOCONN
146 %token BYTES KBYTES MBYTES
147 %token CALLER_ID_WAIT
148 %token CAN_FLOOD
149 %token CHANNEL
150 %token CIDR_BITLEN_IPV4
151 %token CIDR_BITLEN_IPV6
152 %token CLASS
153 %token CONNECT
154 %token CONNECTFREQ
155 %token DEFAULT_FLOODCOUNT
156 %token DEFAULT_SPLIT_SERVER_COUNT
157 %token DEFAULT_SPLIT_USER_COUNT
158 %token DENY
159 %token DESCRIPTION
160 %token DIE
161 %token DISABLE_AUTH
162 %token DISABLE_FAKE_CHANNELS
163 %token DISABLE_REMOTE_COMMANDS
164 %token DOTS_IN_IDENT
165 %token EGDPOOL_PATH
166 %token EMAIL
167 %token ENCRYPTED
168 %token EXCEED_LIMIT
169 %token EXEMPT
170 %token FAILED_OPER_NOTICE
171 %token IRCD_FLAGS
172 %token FLATTEN_LINKS
173 %token GECOS
174 %token GENERAL
175 %token GLINE
176 %token GLINE_DURATION
177 %token GLINE_ENABLE
178 %token GLINE_EXEMPT
179 %token GLINE_REQUEST_DURATION
180 %token GLINE_MIN_CIDR
181 %token GLINE_MIN_CIDR6
182 %token GLOBAL_KILL
183 %token IRCD_AUTH
184 %token NEED_IDENT
185 %token HAVENT_READ_CONF
186 %token HIDDEN
187 %token HIDDEN_NAME
188 %token HIDE_SERVER_IPS
189 %token HIDE_SERVERS
190 %token HIDE_SPOOF_IPS
191 %token HOST
192 %token HUB
193 %token HUB_MASK
194 %token IGNORE_BOGUS_TS
195 %token INVISIBLE_ON_CONNECT
196 %token IP
197 %token KILL
198 %token KILL_CHASE_TIME_LIMIT
199 %token KLINE
200 %token KLINE_EXEMPT
201 %token KNOCK_DELAY
202 %token KNOCK_DELAY_CHANNEL
203 %token LEAF_MASK
204 %token LINKS_DELAY
205 %token LISTEN
206 %token T_LOG
207 %token MAX_ACCEPT
208 %token MAX_BANS
209 %token MAX_CHANS_PER_OPER
210 %token MAX_CHANS_PER_USER
211 %token MAX_GLOBAL
212 %token MAX_IDENT
213 %token MAX_LOCAL
214 %token MAX_NICK_CHANGES
215 %token MAX_NICK_LENGTH
216 %token MAX_NICK_TIME
217 %token MAX_NUMBER
218 %token MAX_TARGETS
219 %token MAX_TOPIC_LENGTH
220 %token MAX_WATCH
221 %token MESSAGE_LOCALE
222 %token MIN_NONWILDCARD
223 %token MIN_NONWILDCARD_SIMPLE
224 %token MODULE
225 %token MODULES
226 %token NAME
227 %token NEED_PASSWORD
228 %token NETWORK_DESC
229 %token NETWORK_NAME
230 %token NICK
231 %token NICK_CHANGES
232 %token NO_CREATE_ON_SPLIT
233 %token NO_JOIN_ON_SPLIT
234 %token NO_OPER_FLOOD
235 %token NO_TILDE
236 %token NUMBER
237 %token NUMBER_PER_CIDR
238 %token NUMBER_PER_IP
239 %token OPERATOR
240 %token OPERS_BYPASS_CALLERID
241 %token OPER_ONLY_UMODES
242 %token OPER_PASS_RESV
243 %token OPER_SPY_T
244 %token OPER_UMODES
245 %token JOIN_FLOOD_COUNT
246 %token JOIN_FLOOD_TIME
247 %token PACE_WAIT
248 %token PACE_WAIT_SIMPLE
249 %token PASSWORD
250 %token PATH
251 %token PING_COOKIE
252 %token PING_TIME
253 %token PORT
254 %token QSTRING
255 %token QUIET_ON_BAN
256 %token REASON
257 %token REDIRPORT
258 %token REDIRSERV
259 %token REGEX_T
260 %token REHASH
261 %token REMOTE
262 %token REMOTEBAN
263 %token RESTRICT_CHANNELS
264 %token RSA_PRIVATE_KEY_FILE
265 %token RSA_PUBLIC_KEY_FILE
266 %token SSL_CERTIFICATE_FILE
267 %token SSL_DH_PARAM_FILE
268 %token T_SSL_CLIENT_METHOD
269 %token T_SSL_SERVER_METHOD
270 %token T_SSLV3
271 %token T_TLSV1
272 %token RESV
273 %token RESV_EXEMPT
274 %token SECONDS MINUTES HOURS DAYS WEEKS
275 %token SENDQ
276 %token SEND_PASSWORD
277 %token SERVERHIDE
278 %token SERVERINFO
279 %token IRCD_SID
280 %token TKLINE_EXPIRE_NOTICES
281 %token T_SHARED
282 %token T_CLUSTER
283 %token TYPE
284 %token SHORT_MOTD
285 %token SPOOF
286 %token SPOOF_NOTICE
287 %token STATS_E_DISABLED
288 %token STATS_I_OPER_ONLY
289 %token STATS_K_OPER_ONLY
290 %token STATS_O_OPER_ONLY
291 %token STATS_P_OPER_ONLY
292 %token TBOOL
293 %token TMASKED
294 %token TS_MAX_DELTA
295 %token TS_WARN_DELTA
296 %token TWODOTS
297 %token T_ALL
298 %token T_BOTS
299 %token T_SOFTCALLERID
300 %token T_CALLERID
301 %token T_CCONN
302 %token T_CCONN_FULL
303 %token T_SSL_CIPHER_LIST
304 %token T_DEAF
305 %token T_DEBUG
306 %token T_DLINE
307 %token T_EXTERNAL
308 %token T_FULL
309 %token T_INVISIBLE
310 %token T_IPV4
311 %token T_IPV6
312 %token T_LOCOPS
313 %token T_MAX_CLIENTS
314 %token T_NCHANGE
315 %token T_OPERWALL
316 %token T_RECVQ
317 %token T_REJ
318 %token T_SERVER
319 %token T_SERVNOTICE
320 %token T_SET
321 %token T_SKILL
322 %token T_SPY
323 %token T_SSL
324 %token T_UMODES
325 %token T_UNAUTH
326 %token T_UNDLINE
327 %token T_UNLIMITED
328 %token T_UNRESV
329 %token T_UNXLINE
330 %token T_GLOBOPS
331 %token T_WALLOP
332 %token T_WEBIRC
333 %token T_RESTART
334 %token T_SERVICE
335 %token T_SERVICES_NAME
336 %token THROTTLE_TIME
337 %token TRUE_NO_OPER_FLOOD
338 %token UNKLINE
339 %token USER
340 %token USE_EGD
341 %token USE_LOGGING
342 %token VHOST
343 %token VHOST6
344 %token XLINE
345 %token WARN_NO_NLINE
346 %token T_SIZE
347 %token T_FILE
348
349 %type <string> QSTRING
350 %type <number> NUMBER
351 %type <number> timespec
352 %type <number> timespec_
353 %type <number> sizespec
354 %type <number> sizespec_
355
356 %%
357 conf:
358 | conf conf_item
359 ;
360
361 conf_item: admin_entry
362 | logging_entry
363 | oper_entry
364 | channel_entry
365 | class_entry
366 | listen_entry
367 | auth_entry
368 | serverinfo_entry
369 | serverhide_entry
370 | resv_entry
371 | service_entry
372 | shared_entry
373 | cluster_entry
374 | connect_entry
375 | kill_entry
376 | deny_entry
377 | exempt_entry
378 | general_entry
379 | gecos_entry
380 | modules_entry
381 | error ';'
382 | error '}'
383 ;
384
385
386 timespec_: { $$ = 0; } | timespec;
387 timespec: NUMBER timespec_
388 {
389 $$ = $1 + $2;
390 }
391 | NUMBER SECONDS timespec_
392 {
393 $$ = $1 + $3;
394 }
395 | NUMBER MINUTES timespec_
396 {
397 $$ = $1 * 60 + $3;
398 }
399 | NUMBER HOURS timespec_
400 {
401 $$ = $1 * 60 * 60 + $3;
402 }
403 | NUMBER DAYS timespec_
404 {
405 $$ = $1 * 60 * 60 * 24 + $3;
406 }
407 | NUMBER WEEKS timespec_
408 {
409 $$ = $1 * 60 * 60 * 24 * 7 + $3;
410 }
411 ;
412
413 sizespec_: { $$ = 0; } | sizespec;
414 sizespec: NUMBER sizespec_ { $$ = $1 + $2; }
415 | NUMBER BYTES sizespec_ { $$ = $1 + $3; }
416 | NUMBER KBYTES sizespec_ { $$ = $1 * 1024 + $3; }
417 | NUMBER MBYTES sizespec_ { $$ = $1 * 1024 * 1024 + $3; }
418 ;
419
420
421 /***************************************************************************
422 * section modules
423 ***************************************************************************/
424 modules_entry: MODULES
425 '{' modules_items '}' ';';
426
427 modules_items: modules_items modules_item | modules_item;
428 modules_item: modules_module | modules_path | error ';' ;
429
430 modules_module: MODULE '=' QSTRING ';'
431 {
432 if (conf_parser_ctx.pass == 2)
433 add_conf_module(libio_basename(yylval.string));
434 };
435
436 modules_path: PATH '=' QSTRING ';'
437 {
438 if (conf_parser_ctx.pass == 2)
439 mod_add_path(yylval.string);
440 };
441
442
443 serverinfo_entry: SERVERINFO '{' serverinfo_items '}' ';';
444
445 serverinfo_items: serverinfo_items serverinfo_item | serverinfo_item ;
446 serverinfo_item: serverinfo_name | serverinfo_vhost |
447 serverinfo_hub | serverinfo_description |
448 serverinfo_network_name | serverinfo_network_desc |
449 serverinfo_max_clients | serverinfo_max_nick_length |
450 serverinfo_max_topic_length | serverinfo_ssl_dh_param_file |
451 serverinfo_rsa_private_key_file | serverinfo_vhost6 |
452 serverinfo_sid | serverinfo_ssl_certificate_file |
453 serverinfo_ssl_client_method | serverinfo_ssl_server_method |
454 serverinfo_ssl_cipher_list |
455 error ';' ;
456
457
458 serverinfo_ssl_client_method: T_SSL_CLIENT_METHOD '=' client_method_types ';' ;
459 serverinfo_ssl_server_method: T_SSL_SERVER_METHOD '=' server_method_types ';' ;
460
461 client_method_types: client_method_types ',' client_method_type_item | client_method_type_item;
462 client_method_type_item: T_SSLV3
463 {
464 #ifdef HAVE_LIBCRYPTO
465 if (conf_parser_ctx.pass == 2 && ServerInfo.client_ctx)
466 SSL_CTX_clear_options(ServerInfo.client_ctx, SSL_OP_NO_SSLv3);
467 #endif
468 } | T_TLSV1
469 {
470 #ifdef HAVE_LIBCRYPTO
471 if (conf_parser_ctx.pass == 2 && ServerInfo.client_ctx)
472 SSL_CTX_clear_options(ServerInfo.client_ctx, SSL_OP_NO_TLSv1);
473 #endif
474 };
475
476 server_method_types: server_method_types ',' server_method_type_item | server_method_type_item;
477 server_method_type_item: T_SSLV3
478 {
479 #ifdef HAVE_LIBCRYPTO
480 if (conf_parser_ctx.pass == 2 && ServerInfo.server_ctx)
481 SSL_CTX_clear_options(ServerInfo.server_ctx, SSL_OP_NO_SSLv3);
482 #endif
483 } | T_TLSV1
484 {
485 #ifdef HAVE_LIBCRYPTO
486 if (conf_parser_ctx.pass == 2 && ServerInfo.server_ctx)
487 SSL_CTX_clear_options(ServerInfo.server_ctx, SSL_OP_NO_TLSv1);
488 #endif
489 };
490
491 serverinfo_ssl_certificate_file: SSL_CERTIFICATE_FILE '=' QSTRING ';'
492 {
493 #ifdef HAVE_LIBCRYPTO
494 if (conf_parser_ctx.pass == 2 && ServerInfo.server_ctx)
495 {
496 if (!ServerInfo.rsa_private_key_file)
497 {
498 yyerror("No rsa_private_key_file specified, SSL disabled");
499 break;
500 }
501
502 if (SSL_CTX_use_certificate_file(ServerInfo.server_ctx, yylval.string,
503 SSL_FILETYPE_PEM) <= 0 ||
504 SSL_CTX_use_certificate_file(ServerInfo.client_ctx, yylval.string,
505 SSL_FILETYPE_PEM) <= 0)
506 {
507 yyerror(ERR_lib_error_string(ERR_get_error()));
508 break;
509 }
510
511 if (SSL_CTX_use_PrivateKey_file(ServerInfo.server_ctx, ServerInfo.rsa_private_key_file,
512 SSL_FILETYPE_PEM) <= 0 ||
513 SSL_CTX_use_PrivateKey_file(ServerInfo.client_ctx, ServerInfo.rsa_private_key_file,
514 SSL_FILETYPE_PEM) <= 0)
515 {
516 yyerror(ERR_lib_error_string(ERR_get_error()));
517 break;
518 }
519
520 if (!SSL_CTX_check_private_key(ServerInfo.server_ctx) ||
521 !SSL_CTX_check_private_key(ServerInfo.client_ctx))
522 {
523 yyerror(ERR_lib_error_string(ERR_get_error()));
524 break;
525 }
526 }
527 #endif
528 };
529
530 serverinfo_rsa_private_key_file: RSA_PRIVATE_KEY_FILE '=' QSTRING ';'
531 {
532 #ifdef HAVE_LIBCRYPTO
533 if (conf_parser_ctx.pass == 1)
534 {
535 BIO *file;
536
537 if (ServerInfo.rsa_private_key)
538 {
539 RSA_free(ServerInfo.rsa_private_key);
540 ServerInfo.rsa_private_key = NULL;
541 }
542
543 if (ServerInfo.rsa_private_key_file)
544 {
545 MyFree(ServerInfo.rsa_private_key_file);
546 ServerInfo.rsa_private_key_file = NULL;
547 }
548
549 ServerInfo.rsa_private_key_file = xstrdup(yylval.string);
550
551 if ((file = BIO_new_file(yylval.string, "r")) == NULL)
552 {
553 yyerror("File open failed, ignoring");
554 break;
555 }
556
557 ServerInfo.rsa_private_key = PEM_read_bio_RSAPrivateKey(file, NULL, 0, NULL);
558
559 BIO_set_close(file, BIO_CLOSE);
560 BIO_free(file);
561
562 if (ServerInfo.rsa_private_key == NULL)
563 {
564 yyerror("Couldn't extract key, ignoring");
565 break;
566 }
567
568 if (!RSA_check_key(ServerInfo.rsa_private_key))
569 {
570 RSA_free(ServerInfo.rsa_private_key);
571 ServerInfo.rsa_private_key = NULL;
572
573 yyerror("Invalid key, ignoring");
574 break;
575 }
576
577 /* require 2048 bit (256 byte) key */
578 if (RSA_size(ServerInfo.rsa_private_key) != 256)
579 {
580 RSA_free(ServerInfo.rsa_private_key);
581 ServerInfo.rsa_private_key = NULL;
582
583 yyerror("Not a 2048 bit key, ignoring");
584 }
585 }
586 #endif
587 };
588
589 serverinfo_ssl_dh_param_file: SSL_DH_PARAM_FILE '=' QSTRING ';'
590 {
591 /* TBD - XXX: error reporting */
592 #ifdef HAVE_LIBCRYPTO
593 if (conf_parser_ctx.pass == 2 && ServerInfo.server_ctx)
594 {
595 BIO *file = BIO_new_file(yylval.string, "r");
596
597 if (file)
598 {
599 DH *dh = PEM_read_bio_DHparams(file, NULL, NULL, NULL);
600
601 BIO_free(file);
602
603 if (dh)
604 {
605 if (DH_size(dh) < 128)
606 ilog(LOG_TYPE_IRCD, "Ignoring serverinfo::ssl_dh_param_file -- need at least a 1024 bit DH prime size");
607 else
608 SSL_CTX_set_tmp_dh(ServerInfo.server_ctx, dh);
609
610 DH_free(dh);
611 }
612 }
613 }
614 #endif
615 };
616
617 serverinfo_ssl_cipher_list: T_SSL_CIPHER_LIST '=' QSTRING ';'
618 {
619 #ifdef HAVE_LIBCRYPTO
620 if (conf_parser_ctx.pass == 2 && ServerInfo.server_ctx)
621 SSL_CTX_set_cipher_list(ServerInfo.server_ctx, yylval.string);
622 #endif
623 };
624
625 serverinfo_name: NAME '=' QSTRING ';'
626 {
627 /* this isn't rehashable */
628 if (conf_parser_ctx.pass == 2 && !ServerInfo.name)
629 {
630 if (valid_servname(yylval.string))
631 ServerInfo.name = xstrdup(yylval.string);
632 else
633 {
634 ilog(LOG_TYPE_IRCD, "Ignoring serverinfo::name -- invalid name. Aborting.");
635 exit(0);
636 }
637 }
638 };
639
640 serverinfo_sid: IRCD_SID '=' QSTRING ';'
641 {
642 /* this isn't rehashable */
643 if (conf_parser_ctx.pass == 2 && !ServerInfo.sid)
644 {
645 if (valid_sid(yylval.string))
646 ServerInfo.sid = xstrdup(yylval.string);
647 else
648 {
649 ilog(LOG_TYPE_IRCD, "Ignoring serverinfo::sid -- invalid SID. Aborting.");
650 exit(0);
651 }
652 }
653 };
654
655 serverinfo_description: DESCRIPTION '=' QSTRING ';'
656 {
657 if (conf_parser_ctx.pass == 2)
658 {
659 MyFree(ServerInfo.description);
660 ServerInfo.description = xstrdup(yylval.string);
661 }
662 };
663
664 serverinfo_network_name: NETWORK_NAME '=' QSTRING ';'
665 {
666 if (conf_parser_ctx.pass == 2)
667 {
668 char *p;
669
670 if ((p = strchr(yylval.string, ' ')) != NULL)
671 p = '\0';
672
673 MyFree(ServerInfo.network_name);
674 ServerInfo.network_name = xstrdup(yylval.string);
675 }
676 };
677
678 serverinfo_network_desc: NETWORK_DESC '=' QSTRING ';'
679 {
680 if (conf_parser_ctx.pass == 2)
681 {
682 MyFree(ServerInfo.network_desc);
683 ServerInfo.network_desc = xstrdup(yylval.string);
684 }
685 };
686
687 serverinfo_vhost: VHOST '=' QSTRING ';'
688 {
689 if (conf_parser_ctx.pass == 2 && *yylval.string != '*')
690 {
691 struct addrinfo hints, *res;
692
693 memset(&hints, 0, sizeof(hints));
694
695 hints.ai_family = AF_UNSPEC;
696 hints.ai_socktype = SOCK_STREAM;
697 hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST;
698
699 if (getaddrinfo(yylval.string, NULL, &hints, &res))
700 ilog(LOG_TYPE_IRCD, "Invalid netmask for server vhost(%s)", yylval.string);
701 else
702 {
703 assert(res != NULL);
704
705 memcpy(&ServerInfo.ip, res->ai_addr, res->ai_addrlen);
706 ServerInfo.ip.ss.ss_family = res->ai_family;
707 ServerInfo.ip.ss_len = res->ai_addrlen;
708 freeaddrinfo(res);
709
710 ServerInfo.specific_ipv4_vhost = 1;
711 }
712 }
713 };
714
715 serverinfo_vhost6: VHOST6 '=' QSTRING ';'
716 {
717 #ifdef IPV6
718 if (conf_parser_ctx.pass == 2 && *yylval.string != '*')
719 {
720 struct addrinfo hints, *res;
721
722 memset(&hints, 0, sizeof(hints));
723
724 hints.ai_family = AF_UNSPEC;
725 hints.ai_socktype = SOCK_STREAM;
726 hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST;
727
728 if (getaddrinfo(yylval.string, NULL, &hints, &res))
729 ilog(LOG_TYPE_IRCD, "Invalid netmask for server vhost6(%s)", yylval.string);
730 else
731 {
732 assert(res != NULL);
733
734 memcpy(&ServerInfo.ip6, res->ai_addr, res->ai_addrlen);
735 ServerInfo.ip6.ss.ss_family = res->ai_family;
736 ServerInfo.ip6.ss_len = res->ai_addrlen;
737 freeaddrinfo(res);
738
739 ServerInfo.specific_ipv6_vhost = 1;
740 }
741 }
742 #endif
743 };
744
745 serverinfo_max_clients: T_MAX_CLIENTS '=' NUMBER ';'
746 {
747 if (conf_parser_ctx.pass != 2)
748 break;
749
750 if ($3 < MAXCLIENTS_MIN)
751 {
752 char buf[IRCD_BUFSIZE];
753
754 snprintf(buf, sizeof(buf), "MAXCLIENTS too low, setting to %d", MAXCLIENTS_MIN);
755 yyerror(buf);
756 ServerInfo.max_clients = MAXCLIENTS_MIN;
757 }
758 else if ($3 > MAXCLIENTS_MAX)
759 {
760 char buf[IRCD_BUFSIZE];
761
762 snprintf(buf, sizeof(buf), "MAXCLIENTS too high, setting to %d", MAXCLIENTS_MAX);
763 yyerror(buf);
764 ServerInfo.max_clients = MAXCLIENTS_MAX;
765 }
766 else
767 ServerInfo.max_clients = $3;
768 };
769
770 serverinfo_max_nick_length: MAX_NICK_LENGTH '=' NUMBER ';'
771 {
772 if (conf_parser_ctx.pass != 2)
773 break;
774
775 if ($3 < 9)
776 {
777 conf_error_report("max_nick_length too low, setting to 9");
778 ServerInfo.max_nick_length = 9;
779 }
780 else if ($3 > NICKLEN)
781 {
782 char buf[IRCD_BUFSIZE];
783
784 snprintf(buf, sizeof(buf), "max_nick_length too high, setting to %d", NICKLEN);
785 conf_error_report(buf);
786 ServerInfo.max_nick_length = NICKLEN;
787 }
788 else
789 ServerInfo.max_nick_length = $3;
790 };
791
792 serverinfo_max_topic_length: MAX_TOPIC_LENGTH '=' NUMBER ';'
793 {
794 if (conf_parser_ctx.pass != 2)
795 break;
796
797 if ($3 < 80)
798 {
799 conf_error_report("max_topic_length too low, setting to 80");
800 ServerInfo.max_topic_length = 80;
801 }
802 else if ($3 > TOPICLEN)
803 {
804 char buf[IRCD_BUFSIZE];
805
806 snprintf(buf, sizeof(buf), "max_topic_length too high, setting to %d", TOPICLEN);
807 conf_error_report(buf);
808 ServerInfo.max_topic_length = TOPICLEN;
809 }
810 else
811 ServerInfo.max_topic_length = $3;
812 };
813
814 serverinfo_hub: HUB '=' TBOOL ';'
815 {
816 if (conf_parser_ctx.pass == 2)
817 ServerInfo.hub = yylval.number;
818 };
819
820 /***************************************************************************
821 * admin section
822 ***************************************************************************/
823 admin_entry: ADMIN '{' admin_items '}' ';' ;
824
825 admin_items: admin_items admin_item | admin_item;
826 admin_item: admin_name | admin_description |
827 admin_email | error ';' ;
828
829 admin_name: NAME '=' QSTRING ';'
830 {
831 if (conf_parser_ctx.pass == 2)
832 {
833 MyFree(AdminInfo.name);
834 AdminInfo.name = xstrdup(yylval.string);
835 }
836 };
837
838 admin_email: EMAIL '=' QSTRING ';'
839 {
840 if (conf_parser_ctx.pass == 2)
841 {
842 MyFree(AdminInfo.email);
843 AdminInfo.email = xstrdup(yylval.string);
844 }
845 };
846
847 admin_description: DESCRIPTION '=' QSTRING ';'
848 {
849 if (conf_parser_ctx.pass == 2)
850 {
851 MyFree(AdminInfo.description);
852 AdminInfo.description = xstrdup(yylval.string);
853 }
854 };
855
856 /***************************************************************************
857 * section logging
858 ***************************************************************************/
859 logging_entry: T_LOG '{' logging_items '}' ';' ;
860 logging_items: logging_items logging_item | logging_item ;
861
862 logging_item: logging_use_logging | logging_file_entry |
863 error ';' ;
864
865 logging_use_logging: USE_LOGGING '=' TBOOL ';'
866 {
867 if (conf_parser_ctx.pass == 2)
868 ConfigLoggingEntry.use_logging = yylval.number;
869 };
870
871 logging_file_entry:
872 {
873 if (conf_parser_ctx.pass == 2)
874 reset_block_state();
875 } T_FILE '{' logging_file_items '}' ';'
876 {
877 if (conf_parser_ctx.pass != 2)
878 break;
879
880 if (block_state.type.value && block_state.file.buf[0])
881 log_add_file(block_state.type.value, block_state.size.value,
882 block_state.file.buf);
883 };
884
885 logging_file_items: logging_file_items logging_file_item |
886 logging_file_item ;
887
888 logging_file_item: logging_file_name | logging_file_type |
889 logging_file_size | error ';' ;
890
891 logging_file_name: NAME '=' QSTRING ';'
892 {
893 if (conf_parser_ctx.pass != 2)
894 break;
895
896 strlcpy(block_state.file.buf, yylval.string, sizeof(block_state.file.buf));
897 }
898
899 logging_file_size: T_SIZE '=' sizespec ';'
900 {
901 block_state.size.value = $3;
902 } | T_SIZE '=' T_UNLIMITED ';'
903 {
904 block_state.size.value = 0;
905 };
906
907 logging_file_type: TYPE
908 {
909 if (conf_parser_ctx.pass == 2)
910 block_state.type.value = 0;
911 } '=' logging_file_type_items ';' ;
912
913 logging_file_type_items: logging_file_type_items ',' logging_file_type_item | logging_file_type_item;
914 logging_file_type_item: USER
915 {
916 if (conf_parser_ctx.pass == 2)
917 block_state.type.value = LOG_TYPE_USER;
918 } | OPERATOR
919 {
920 if (conf_parser_ctx.pass == 2)
921 block_state.type.value = LOG_TYPE_OPER;
922 } | GLINE
923 {
924 if (conf_parser_ctx.pass == 2)
925 block_state.type.value = LOG_TYPE_GLINE;
926 } | T_DLINE
927 {
928 if (conf_parser_ctx.pass == 2)
929 block_state.type.value = LOG_TYPE_DLINE;
930 } | KLINE
931 {
932 if (conf_parser_ctx.pass == 2)
933 block_state.type.value = LOG_TYPE_KLINE;
934 } | KILL
935 {
936 if (conf_parser_ctx.pass == 2)
937 block_state.type.value = LOG_TYPE_KILL;
938 } | T_DEBUG
939 {
940 if (conf_parser_ctx.pass == 2)
941 block_state.type.value = LOG_TYPE_DEBUG;
942 };
943
944
945 /***************************************************************************
946 * section oper
947 ***************************************************************************/
948 oper_entry: OPERATOR
949 {
950 if (conf_parser_ctx.pass != 2)
951 break;
952
953 reset_block_state();
954 block_state.flags.value |= CONF_FLAGS_ENCRYPTED;
955 } '{' oper_items '}' ';'
956 {
957 dlink_node *ptr = NULL;
958
959 if (conf_parser_ctx.pass != 2)
960 break;
961
962 if (!block_state.name.buf[0])
963 break;
964 #ifdef HAVE_LIBCRYPTO
965 if (!(block_state.file.buf[0] ||
966 block_state.rpass.buf[0]))
967 break;
968 #else
969 if (!block_state.rpass.buf[0])
970 break;
971 #endif
972
973 DLINK_FOREACH(ptr, block_state.mask.list.head)
974 {
975 struct MaskItem *conf = NULL;
976 struct split_nuh_item nuh;
977
978 nuh.nuhmask = ptr->data;
979 nuh.nickptr = NULL;
980 nuh.userptr = block_state.user.buf;
981 nuh.hostptr = block_state.host.buf;
982 nuh.nicksize = 0;
983 nuh.usersize = sizeof(block_state.user.buf);
984 nuh.hostsize = sizeof(block_state.host.buf);
985 split_nuh(&nuh);
986
987 conf = conf_make(CONF_OPER);
988 conf->name = xstrdup(block_state.name.buf);
989 conf->user = xstrdup(block_state.user.buf);
990 conf->host = xstrdup(block_state.host.buf);
991
992 if (block_state.rpass.buf[0])
993 conf->passwd = xstrdup(block_state.rpass.buf);
994
995 conf->flags = block_state.flags.value;
996 conf->modes = block_state.modes.value;
997 conf->port = block_state.port.value;
998 conf->htype = parse_netmask(conf->host, &conf->addr, &conf->bits);
999
1000 conf_add_class_to_conf(conf, block_state.class.buf);
1001
1002 #ifdef HAVE_LIBCRYPTO
1003 if (block_state.file.buf[0])
1004 {
1005 BIO *file = NULL;
1006 RSA *pkey = NULL;
1007
1008 if ((file = BIO_new_file(block_state.file.buf, "r")) == NULL)
1009 {
1010 yyerror("Ignoring rsa_public_key_file -- file doesn't exist");
1011 break;
1012 }
1013
1014 if ((pkey = PEM_read_bio_RSA_PUBKEY(file, NULL, 0, NULL)) == NULL)
1015 yyerror("Ignoring rsa_public_key_file -- Key invalid; check key syntax.");
1016
1017 conf->rsa_public_key = pkey;
1018 BIO_set_close(file, BIO_CLOSE);
1019 BIO_free(file);
1020 }
1021 #endif /* HAVE_LIBCRYPTO */
1022 }
1023 };
1024
1025 oper_items: oper_items oper_item | oper_item;
1026 oper_item: oper_name | oper_user | oper_password |
1027 oper_umodes | oper_class | oper_encrypted |
1028 oper_rsa_public_key_file | oper_flags | error ';' ;
1029
1030 oper_name: NAME '=' QSTRING ';'
1031 {
1032 if (conf_parser_ctx.pass == 2)
1033 strlcpy(block_state.name.buf, yylval.string, sizeof(block_state.name.buf));
1034 };
1035
1036 oper_user: USER '=' QSTRING ';'
1037 {
1038 if (conf_parser_ctx.pass == 2)
1039 dlinkAdd(xstrdup(yylval.string), make_dlink_node(), &block_state.mask.list);
1040 };
1041
1042 oper_password: PASSWORD '=' QSTRING ';'
1043 {
1044 if (conf_parser_ctx.pass == 2)
1045 strlcpy(block_state.rpass.buf, yylval.string, sizeof(block_state.rpass.buf));
1046 };
1047
1048 oper_encrypted: ENCRYPTED '=' TBOOL ';'
1049 {
1050 if (conf_parser_ctx.pass == 2)
1051 {
1052 if (yylval.number)
1053 block_state.flags.value |= CONF_FLAGS_ENCRYPTED;
1054 else
1055 block_state.flags.value &= ~CONF_FLAGS_ENCRYPTED;
1056 }
1057 };
1058
1059 oper_rsa_public_key_file: RSA_PUBLIC_KEY_FILE '=' QSTRING ';'
1060 {
1061 if (conf_parser_ctx.pass == 2)
1062 strlcpy(block_state.file.buf, yylval.string, sizeof(block_state.file.buf));
1063 };
1064
1065 oper_class: CLASS '=' QSTRING ';'
1066 {
1067 if (conf_parser_ctx.pass == 2)
1068 strlcpy(block_state.class.buf, yylval.string, sizeof(block_state.class.buf));
1069 };
1070
1071 oper_umodes: T_UMODES
1072 {
1073 if (conf_parser_ctx.pass == 2)
1074 block_state.modes.value = 0;
1075 } '=' oper_umodes_items ';' ;
1076
1077 oper_umodes_items: oper_umodes_items ',' oper_umodes_item | oper_umodes_item;
1078 oper_umodes_item: T_BOTS
1079 {
1080 if (conf_parser_ctx.pass == 2)
1081 block_state.modes.value |= UMODE_BOTS;
1082 } | T_CCONN
1083 {
1084 if (conf_parser_ctx.pass == 2)
1085 block_state.modes.value |= UMODE_CCONN;
1086 } | T_CCONN_FULL
1087 {
1088 if (conf_parser_ctx.pass == 2)
1089 block_state.modes.value |= UMODE_CCONN_FULL;
1090 } | T_DEAF
1091 {
1092 if (conf_parser_ctx.pass == 2)
1093 block_state.modes.value |= UMODE_DEAF;
1094 } | T_DEBUG
1095 {
1096 if (conf_parser_ctx.pass == 2)
1097 block_state.modes.value |= UMODE_DEBUG;
1098 } | T_FULL
1099 {
1100 if (conf_parser_ctx.pass == 2)
1101 block_state.modes.value |= UMODE_FULL;
1102 } | HIDDEN
1103 {
1104 if (conf_parser_ctx.pass == 2)
1105 block_state.modes.value |= UMODE_HIDDEN;
1106 } | T_SKILL
1107 {
1108 if (conf_parser_ctx.pass == 2)
1109 block_state.modes.value |= UMODE_SKILL;
1110 } | T_NCHANGE
1111 {
1112 if (conf_parser_ctx.pass == 2)
1113 block_state.modes.value |= UMODE_NCHANGE;
1114 } | T_REJ
1115 {
1116 if (conf_parser_ctx.pass == 2)
1117 block_state.modes.value |= UMODE_REJ;
1118 } | T_UNAUTH
1119 {
1120 if (conf_parser_ctx.pass == 2)
1121 block_state.modes.value |= UMODE_UNAUTH;
1122 } | T_SPY
1123 {
1124 if (conf_parser_ctx.pass == 2)
1125 block_state.modes.value |= UMODE_SPY;
1126 } | T_EXTERNAL
1127 {
1128 if (conf_parser_ctx.pass == 2)
1129 block_state.modes.value |= UMODE_EXTERNAL;
1130 } | T_OPERWALL
1131 {
1132 if (conf_parser_ctx.pass == 2)
1133 block_state.modes.value |= UMODE_OPERWALL;
1134 } | T_SERVNOTICE
1135 {
1136 if (conf_parser_ctx.pass == 2)
1137 block_state.modes.value |= UMODE_SERVNOTICE;
1138 } | T_INVISIBLE
1139 {
1140 if (conf_parser_ctx.pass == 2)
1141 block_state.modes.value |= UMODE_INVISIBLE;
1142 } | T_WALLOP
1143 {
1144 if (conf_parser_ctx.pass == 2)
1145 block_state.modes.value |= UMODE_WALLOP;
1146 } | T_SOFTCALLERID
1147 {
1148 if (conf_parser_ctx.pass == 2)
1149 block_state.modes.value |= UMODE_SOFTCALLERID;
1150 } | T_CALLERID
1151 {
1152 if (conf_parser_ctx.pass == 2)
1153 block_state.modes.value |= UMODE_CALLERID;
1154 } | T_LOCOPS
1155 {
1156 if (conf_parser_ctx.pass == 2)
1157 block_state.modes.value |= UMODE_LOCOPS;
1158 };
1159
1160 oper_flags: IRCD_FLAGS
1161 {
1162 if (conf_parser_ctx.pass == 2)
1163 block_state.port.value = 0;
1164 } '=' oper_flags_items ';';
1165
1166 oper_flags_items: oper_flags_items ',' oper_flags_item | oper_flags_item;
1167 oper_flags_item: GLOBAL_KILL
1168 {
1169 if (conf_parser_ctx.pass == 2)
1170 block_state.port.value |= OPER_FLAG_GLOBAL_KILL;
1171 } | REMOTE
1172 {
1173 if (conf_parser_ctx.pass == 2)
1174 block_state.port.value |= OPER_FLAG_REMOTE;
1175 } | KLINE
1176 {
1177 if (conf_parser_ctx.pass == 2)
1178 block_state.port.value |= OPER_FLAG_K;
1179 } | UNKLINE
1180 {
1181 if (conf_parser_ctx.pass == 2)
1182 block_state.port.value |= OPER_FLAG_UNKLINE;
1183 } | T_DLINE
1184 {
1185 if (conf_parser_ctx.pass == 2)
1186 block_state.port.value |= OPER_FLAG_DLINE;
1187 } | T_UNDLINE
1188 {
1189 if (conf_parser_ctx.pass == 2)
1190 block_state.port.value |= OPER_FLAG_UNDLINE;
1191 } | XLINE
1192 {
1193 if (conf_parser_ctx.pass == 2)
1194 block_state.port.value |= OPER_FLAG_X;
1195 } | GLINE
1196 {
1197 if (conf_parser_ctx.pass == 2)
1198 block_state.port.value |= OPER_FLAG_GLINE;
1199 } | DIE
1200 {
1201 if (conf_parser_ctx.pass == 2)
1202 block_state.port.value |= OPER_FLAG_DIE;
1203 } | T_RESTART
1204 {
1205 if (conf_parser_ctx.pass == 2)
1206 block_state.port.value |= OPER_FLAG_RESTART;
1207 } | REHASH
1208 {
1209 if (conf_parser_ctx.pass == 2)
1210 block_state.port.value |= OPER_FLAG_REHASH;
1211 } | ADMIN
1212 {
1213 if (conf_parser_ctx.pass == 2)
1214 block_state.port.value |= OPER_FLAG_ADMIN;
1215 } | NICK_CHANGES
1216 {
1217 if (conf_parser_ctx.pass == 2)
1218 block_state.port.value |= OPER_FLAG_N;
1219 } | T_OPERWALL
1220 {
1221 if (conf_parser_ctx.pass == 2)
1222 block_state.port.value |= OPER_FLAG_OPERWALL;
1223 } | T_GLOBOPS
1224 {
1225 if (conf_parser_ctx.pass == 2)
1226 block_state.port.value |= OPER_FLAG_GLOBOPS;
1227 } | OPER_SPY_T
1228 {
1229 if (conf_parser_ctx.pass == 2)
1230 block_state.port.value |= OPER_FLAG_OPER_SPY;
1231 } | REMOTEBAN
1232 {
1233 if (conf_parser_ctx.pass == 2)
1234 block_state.port.value |= OPER_FLAG_REMOTEBAN;
1235 } | T_SET
1236 {
1237 if (conf_parser_ctx.pass == 2)
1238 block_state.port.value |= OPER_FLAG_SET;
1239 } | MODULE
1240 {
1241 if (conf_parser_ctx.pass == 2)
1242 block_state.port.value |= OPER_FLAG_MODULE;
1243 };
1244
1245
1246 /***************************************************************************
1247 * section class
1248 ***************************************************************************/
1249 class_entry: CLASS
1250 {
1251 if (conf_parser_ctx.pass != 1)
1252 break;
1253
1254 reset_block_state();
1255
1256 block_state.ping_freq.value = DEFAULT_PINGFREQUENCY;
1257 block_state.con_freq.value = DEFAULT_CONNECTFREQUENCY;
1258 block_state.max_total.value = MAXIMUM_LINKS_DEFAULT;
1259 block_state.max_sendq.value = DEFAULT_SENDQ;
1260 block_state.max_recvq.value = DEFAULT_RECVQ;
1261
1262 } '{' class_items '}' ';'
1263 {
1264 struct ClassItem *class = NULL;
1265
1266 if (conf_parser_ctx.pass != 1)
1267 break;
1268
1269 if (!block_state.class.buf[0])
1270 break;
1271
1272 if (!(class = class_find(block_state.class.buf, 0)))
1273 class = class_make();
1274
1275 class->active = 1;
1276 MyFree(class->name);
1277 class->name = xstrdup(block_state.class.buf);
1278 class->ping_freq = block_state.ping_freq.value;
1279 class->max_perip = block_state.max_perip.value;
1280 class->con_freq = block_state.con_freq.value;
1281 class->max_total = block_state.max_total.value;
1282 class->max_global = block_state.max_global.value;
1283 class->max_local = block_state.max_local.value;
1284 class->max_ident = block_state.max_ident.value;
1285 class->max_sendq = block_state.max_sendq.value;
1286 class->max_recvq = block_state.max_recvq.value;
1287
1288 if (class->number_per_cidr && block_state.number_per_cidr.value)
1289 if ((class->cidr_bitlen_ipv4 && block_state.cidr_bitlen_ipv4.value) ||
1290 (class->cidr_bitlen_ipv6 && block_state.cidr_bitlen_ipv6.value))
1291 if ((class->cidr_bitlen_ipv4 != block_state.cidr_bitlen_ipv4.value) ||
1292 (class->cidr_bitlen_ipv6 != block_state.cidr_bitlen_ipv6.value))
1293 rebuild_cidr_list(class);
1294
1295 class->cidr_bitlen_ipv4 = block_state.cidr_bitlen_ipv4.value;
1296 class->cidr_bitlen_ipv6 = block_state.cidr_bitlen_ipv6.value;
1297 class->number_per_cidr = block_state.number_per_cidr.value;
1298 };
1299
1300 class_items: class_items class_item | class_item;
1301 class_item: class_name |
1302 class_cidr_bitlen_ipv4 | class_cidr_bitlen_ipv6 |
1303 class_ping_time |
1304 class_number_per_cidr |
1305 class_number_per_ip |
1306 class_connectfreq |
1307 class_max_number |
1308 class_max_global |
1309 class_max_local |
1310 class_max_ident |
1311 class_sendq | class_recvq |
1312 error ';' ;
1313
1314 class_name: NAME '=' QSTRING ';'
1315 {
1316 if (conf_parser_ctx.pass == 1)
1317 strlcpy(block_state.class.buf, yylval.string, sizeof(block_state.class.buf));
1318 };
1319
1320 class_ping_time: PING_TIME '=' timespec ';'
1321 {
1322 if (conf_parser_ctx.pass == 1)
1323 block_state.ping_freq.value = $3;
1324 };
1325
1326 class_number_per_ip: NUMBER_PER_IP '=' NUMBER ';'
1327 {
1328 if (conf_parser_ctx.pass == 1)
1329 block_state.max_perip.value = $3;
1330 };
1331
1332 class_connectfreq: CONNECTFREQ '=' timespec ';'
1333 {
1334 if (conf_parser_ctx.pass == 1)
1335 block_state.con_freq.value = $3;
1336 };
1337
1338 class_max_number: MAX_NUMBER '=' NUMBER ';'
1339 {
1340 if (conf_parser_ctx.pass == 1)
1341 block_state.max_total.value = $3;
1342 };
1343
1344 class_max_global: MAX_GLOBAL '=' NUMBER ';'
1345 {
1346 if (conf_parser_ctx.pass == 1)
1347 block_state.max_global.value = $3;
1348 };
1349
1350 class_max_local: MAX_LOCAL '=' NUMBER ';'
1351 {
1352 if (conf_parser_ctx.pass == 1)
1353 block_state.max_local.value = $3;
1354 };
1355
1356 class_max_ident: MAX_IDENT '=' NUMBER ';'
1357 {
1358 if (conf_parser_ctx.pass == 1)
1359 block_state.max_ident.value = $3;
1360 };
1361
1362 class_sendq: SENDQ '=' sizespec ';'
1363 {
1364 if (conf_parser_ctx.pass == 1)
1365 block_state.max_sendq.value = $3;
1366 };
1367
1368 class_recvq: T_RECVQ '=' sizespec ';'
1369 {
1370 if (conf_parser_ctx.pass == 1)
1371 if ($3 >= CLIENT_FLOOD_MIN && $3 <= CLIENT_FLOOD_MAX)
1372 block_state.max_recvq.value = $3;
1373 };
1374
1375 class_cidr_bitlen_ipv4: CIDR_BITLEN_IPV4 '=' NUMBER ';'
1376 {
1377 if (conf_parser_ctx.pass == 1)
1378 block_state.cidr_bitlen_ipv4.value = $3 > 32 ? 32 : $3;
1379 };
1380
1381 class_cidr_bitlen_ipv6: CIDR_BITLEN_IPV6 '=' NUMBER ';'
1382 {
1383 if (conf_parser_ctx.pass == 1)
1384 block_state.cidr_bitlen_ipv6.value = $3 > 128 ? 128 : $3;
1385 };
1386
1387 class_number_per_cidr: NUMBER_PER_CIDR '=' NUMBER ';'
1388 {
1389 if (conf_parser_ctx.pass == 1)
1390 block_state.number_per_cidr.value = $3;
1391 };
1392
1393 /***************************************************************************
1394 * section listen
1395 ***************************************************************************/
1396 listen_entry: LISTEN
1397 {
1398 if (conf_parser_ctx.pass == 2)
1399 reset_block_state();
1400 } '{' listen_items '}' ';';
1401
1402 listen_flags: IRCD_FLAGS
1403 {
1404 block_state.flags.value = 0;
1405 } '=' listen_flags_items ';';
1406
1407 listen_flags_items: listen_flags_items ',' listen_flags_item | listen_flags_item;
1408 listen_flags_item: T_SSL
1409 {
1410 if (conf_parser_ctx.pass == 2)
1411 block_state.flags.value |= LISTENER_SSL;
1412 } | HIDDEN
1413 {
1414 if (conf_parser_ctx.pass == 2)
1415 block_state.flags.value |= LISTENER_HIDDEN;
1416 } | T_SERVER
1417 {
1418 if (conf_parser_ctx.pass == 2)
1419 block_state.flags.value |= LISTENER_SERVER;
1420 };
1421
1422 listen_items: listen_items listen_item | listen_item;
1423 listen_item: listen_port | listen_flags | listen_address | listen_host | error ';';
1424
1425 listen_port: PORT '=' port_items { block_state.flags.value = 0; } ';';
1426
1427 port_items: port_items ',' port_item | port_item;
1428
1429 port_item: NUMBER
1430 {
1431 if (conf_parser_ctx.pass == 2)
1432 {
1433 if (block_state.flags.value & LISTENER_SSL)
1434 #ifdef HAVE_LIBCRYPTO
1435 if (!ServerInfo.server_ctx)
1436 #endif
1437 {
1438 yyerror("SSL not available - port closed");
1439 break;
1440 }
1441 add_listener($1, block_state.addr.buf, block_state.flags.value);
1442 }
1443 } | NUMBER TWODOTS NUMBER
1444 {
1445 if (conf_parser_ctx.pass == 2)
1446 {
1447 int i;
1448
1449 if (block_state.flags.value & LISTENER_SSL)
1450 #ifdef HAVE_LIBCRYPTO
1451 if (!ServerInfo.server_ctx)
1452 #endif
1453 {
1454 yyerror("SSL not available - port closed");
1455 break;
1456 }
1457
1458 for (i = $1; i <= $3; ++i)
1459 add_listener(i, block_state.addr.buf, block_state.flags.value);
1460 }
1461 };
1462
1463 listen_address: IP '=' QSTRING ';'
1464 {
1465 if (conf_parser_ctx.pass == 2)
1466 strlcpy(block_state.addr.buf, yylval.string, sizeof(block_state.addr.buf));
1467 };
1468
1469 listen_host: HOST '=' QSTRING ';'
1470 {
1471 if (conf_parser_ctx.pass == 2)
1472 strlcpy(block_state.addr.buf, yylval.string, sizeof(block_state.addr.buf));
1473 };
1474
1475 /***************************************************************************
1476 * section auth
1477 ***************************************************************************/
1478 auth_entry: IRCD_AUTH
1479 {
1480 if (conf_parser_ctx.pass == 2)
1481 reset_block_state();
1482 } '{' auth_items '}' ';'
1483 {
1484 dlink_node *ptr = NULL;
1485
1486 if (conf_parser_ctx.pass != 2)
1487 break;
1488
1489 DLINK_FOREACH(ptr, block_state.mask.list.head)
1490 {
1491 struct MaskItem *conf = NULL;
1492 struct split_nuh_item nuh;
1493
1494 nuh.nuhmask = ptr->data;
1495 nuh.nickptr = NULL;
1496 nuh.userptr = block_state.user.buf;
1497 nuh.hostptr = block_state.host.buf;
1498 nuh.nicksize = 0;
1499 nuh.usersize = sizeof(block_state.user.buf);
1500 nuh.hostsize = sizeof(block_state.host.buf);
1501 split_nuh(&nuh);
1502
1503 conf = conf_make(CONF_CLIENT);
1504 conf->user = xstrdup(collapse(block_state.user.buf));
1505 conf->host = xstrdup(collapse(block_state.host.buf));
1506
1507 if (block_state.rpass.buf[0])
1508 conf->passwd = xstrdup(block_state.rpass.buf);
1509 if (block_state.name.buf[0])
1510 conf->passwd = xstrdup(block_state.name.buf);
1511
1512 conf->flags = block_state.flags.value;
1513 conf->port = block_state.port.value;
1514
1515 conf_add_class_to_conf(conf, block_state.class.buf);
1516 add_conf_by_address(CONF_CLIENT, conf);
1517 }
1518 };
1519
1520 auth_items: auth_items auth_item | auth_item;
1521 auth_item: auth_user | auth_passwd | auth_class | auth_flags |
1522 auth_spoof | auth_redir_serv | auth_redir_port |
1523 auth_encrypted | error ';' ;
1524
1525 auth_user: USER '=' QSTRING ';'
1526 {
1527 if (conf_parser_ctx.pass == 2)
1528 dlinkAdd(xstrdup(yylval.string), make_dlink_node(), &block_state.mask.list);
1529 };
1530
1531 auth_passwd: PASSWORD '=' QSTRING ';'
1532 {
1533 if (conf_parser_ctx.pass == 2)
1534 strlcpy(block_state.rpass.buf, yylval.string, sizeof(block_state.rpass.buf));
1535 };
1536
1537 auth_class: CLASS '=' QSTRING ';'
1538 {
1539 if (conf_parser_ctx.pass == 2)
1540 strlcpy(block_state.class.buf, yylval.string, sizeof(block_state.class.buf));
1541 };
1542
1543 auth_encrypted: ENCRYPTED '=' TBOOL ';'
1544 {
1545 if (conf_parser_ctx.pass == 2)
1546 {
1547 if (yylval.number)
1548 block_state.flags.value |= CONF_FLAGS_ENCRYPTED;
1549 else
1550 block_state.flags.value &= ~CONF_FLAGS_ENCRYPTED;
1551 }
1552 };
1553
1554 auth_flags: IRCD_FLAGS
1555 {
1556 if (conf_parser_ctx.pass == 2)
1557 block_state.flags.value &= CONF_FLAGS_ENCRYPTED;
1558 } '=' auth_flags_items ';';
1559
1560 auth_flags_items: auth_flags_items ',' auth_flags_item | auth_flags_item;
1561 auth_flags_item: SPOOF_NOTICE
1562 {
1563 if (conf_parser_ctx.pass == 2)
1564 block_state.flags.value |= CONF_FLAGS_SPOOF_NOTICE;
1565 } | EXCEED_LIMIT
1566 {
1567 if (conf_parser_ctx.pass == 2)
1568 block_state.flags.value |= CONF_FLAGS_NOLIMIT;
1569 } | KLINE_EXEMPT
1570 {
1571 if (conf_parser_ctx.pass == 2)
1572 block_state.flags.value |= CONF_FLAGS_EXEMPTKLINE;
1573 } | NEED_IDENT
1574 {
1575 if (conf_parser_ctx.pass == 2)
1576 block_state.flags.value |= CONF_FLAGS_NEED_IDENTD;
1577 } | CAN_FLOOD
1578 {
1579 if (conf_parser_ctx.pass == 2)
1580 block_state.flags.value |= CONF_FLAGS_CAN_FLOOD;
1581 } | NO_TILDE
1582 {
1583 if (conf_parser_ctx.pass == 2)
1584 block_state.flags.value |= CONF_FLAGS_NO_TILDE;
1585 } | GLINE_EXEMPT
1586 {
1587 if (conf_parser_ctx.pass == 2)
1588 block_state.flags.value |= CONF_FLAGS_EXEMPTGLINE;
1589 } | RESV_EXEMPT
1590 {
1591 if (conf_parser_ctx.pass == 2)
1592 block_state.flags.value |= CONF_FLAGS_EXEMPTRESV;
1593 } | T_WEBIRC
1594 {
1595 if (conf_parser_ctx.pass == 2)
1596 block_state.flags.value |= CONF_FLAGS_WEBIRC;
1597 } | NEED_PASSWORD
1598 {
1599 if (conf_parser_ctx.pass == 2)
1600 block_state.flags.value |= CONF_FLAGS_NEED_PASSWORD;
1601 };
1602
1603 auth_spoof: SPOOF '=' QSTRING ';'
1604 {
1605 if (conf_parser_ctx.pass != 2)
1606 break;
1607
1608 if (strlen(yylval.string) <= HOSTLEN && valid_hostname(yylval.string))
1609 {
1610 strlcpy(block_state.name.buf, yylval.string, sizeof(block_state.name.buf));
1611 block_state.flags.value |= CONF_FLAGS_SPOOF_IP;
1612 }
1613 else
1614 ilog(LOG_TYPE_IRCD, "Spoof either is too long or contains invalid characters. Ignoring it.");
1615 };
1616
1617 auth_redir_serv: REDIRSERV '=' QSTRING ';'
1618 {
1619 if (conf_parser_ctx.pass != 2)
1620 break;
1621
1622 strlcpy(block_state.name.buf, yylval.string, sizeof(block_state.name.buf));
1623 block_state.flags.value |= CONF_FLAGS_REDIR;
1624 };
1625
1626 auth_redir_port: REDIRPORT '=' NUMBER ';'
1627 {
1628 if (conf_parser_ctx.pass != 2)
1629 break;
1630
1631 block_state.flags.value |= CONF_FLAGS_REDIR;
1632 block_state.port.value = $3;
1633 };
1634
1635
1636 /***************************************************************************
1637 * section resv
1638 ***************************************************************************/
1639 resv_entry: RESV
1640 {
1641 if (conf_parser_ctx.pass != 2)
1642 break;
1643
1644 reset_block_state();
1645 strlcpy(block_state.rpass.buf, CONF_NOREASON, sizeof(block_state.rpass.buf));
1646 } '{' resv_items '}' ';';
1647
1648 resv_items: resv_items resv_item | resv_item;
1649 resv_item: resv_creason | resv_channel | resv_nick | error ';' ;
1650
1651 resv_creason: REASON '=' QSTRING ';'
1652 {
1653 if (conf_parser_ctx.pass == 2)
1654 strlcpy(block_state.rpass.buf, yylval.string, sizeof(block_state.rpass.buf));
1655 };
1656
1657 resv_channel: CHANNEL '=' QSTRING ';'
1658 {
1659 if (conf_parser_ctx.pass != 2)
1660 break;
1661
1662 if (IsChanPrefix(*yylval.string))
1663 create_channel_resv(yylval.string, block_state.rpass.buf, 1);
1664 };
1665
1666 resv_nick: NICK '=' QSTRING ';'
1667 {
1668 if (conf_parser_ctx.pass == 2)
1669 create_nick_resv(yylval.string, block_state.rpass.buf, 1);
1670 };
1671
1672 /***************************************************************************
1673 * section service
1674 ***************************************************************************/
1675 service_entry: T_SERVICE '{' service_items '}' ';';
1676
1677 service_items: service_items service_item | service_item;
1678 service_item: service_name | error;
1679
1680 service_name: NAME '=' QSTRING ';'
1681 {
1682 if (conf_parser_ctx.pass == 2)
1683 {
1684 if (valid_servname(yylval.string))
1685 {
1686 struct MaskItem *conf = conf_make(CONF_SERVICE);
1687 conf->name = xstrdup(yylval.string);
1688 }
1689 }
1690 };
1691
1692 /***************************************************************************
1693 * section shared, for sharing remote klines etc.
1694 ***************************************************************************/
1695 shared_entry: T_SHARED
1696 {
1697 if (conf_parser_ctx.pass != 2)
1698 break;
1699
1700 reset_block_state();
1701
1702 strlcpy(block_state.name.buf, "*", sizeof(block_state.name.buf));
1703 strlcpy(block_state.user.buf, "*", sizeof(block_state.user.buf));
1704 strlcpy(block_state.host.buf, "*", sizeof(block_state.host.buf));
1705 block_state.flags.value = SHARED_ALL;
1706 } '{' shared_items '}' ';'
1707 {
1708 struct MaskItem *conf = NULL;
1709
1710 if (conf_parser_ctx.pass != 2)
1711 break;
1712
1713 conf = conf_make(CONF_ULINE);
1714 conf->flags = block_state.flags.value;
1715 conf->name = xstrdup(block_state.name.buf);
1716 conf->user = xstrdup(block_state.user.buf);
1717 conf->user = xstrdup(block_state.host.buf);
1718 };
1719
1720 shared_items: shared_items shared_item | shared_item;
1721 shared_item: shared_name | shared_user | shared_type | error ';' ;
1722
1723 shared_name: NAME '=' QSTRING ';'
1724 {
1725 if (conf_parser_ctx.pass == 2)
1726 strlcpy(block_state.name.buf, yylval.string, sizeof(block_state.name.buf));
1727 };
1728
1729 shared_user: USER '=' QSTRING ';'
1730 {
1731 if (conf_parser_ctx.pass == 2)
1732 {
1733 struct split_nuh_item nuh;
1734
1735 nuh.nuhmask = yylval.string;
1736 nuh.nickptr = NULL;
1737 nuh.userptr = block_state.user.buf;
1738 nuh.hostptr = block_state.host.buf;
1739
1740 nuh.nicksize = 0;
1741 nuh.usersize = sizeof(block_state.user.buf);
1742 nuh.hostsize = sizeof(block_state.host.buf);
1743
1744 split_nuh(&nuh);
1745 }
1746 };
1747
1748 shared_type: TYPE
1749 {
1750 if (conf_parser_ctx.pass == 2)
1751 block_state.flags.value = 0;
1752 } '=' shared_types ';' ;
1753
1754 shared_types: shared_types ',' shared_type_item | shared_type_item;
1755 shared_type_item: KLINE
1756 {
1757 if (conf_parser_ctx.pass == 2)
1758 block_state.flags.value |= SHARED_KLINE;
1759 } | UNKLINE
1760 {
1761 if (conf_parser_ctx.pass == 2)
1762 block_state.flags.value |= SHARED_UNKLINE;
1763 } | T_DLINE
1764 {
1765 if (conf_parser_ctx.pass == 2)
1766 block_state.flags.value |= SHARED_DLINE;
1767 } | T_UNDLINE
1768 {
1769 if (conf_parser_ctx.pass == 2)
1770 block_state.flags.value |= SHARED_UNDLINE;
1771 } | XLINE
1772 {
1773 if (conf_parser_ctx.pass == 2)
1774 block_state.flags.value |= SHARED_XLINE;
1775 } | T_UNXLINE
1776 {
1777 if (conf_parser_ctx.pass == 2)
1778 block_state.flags.value |= SHARED_UNXLINE;
1779 } | RESV
1780 {
1781 if (conf_parser_ctx.pass == 2)
1782 block_state.flags.value |= SHARED_RESV;
1783 } | T_UNRESV
1784 {
1785 if (conf_parser_ctx.pass == 2)
1786 block_state.flags.value |= SHARED_UNRESV;
1787 } | T_LOCOPS
1788 {
1789 if (conf_parser_ctx.pass == 2)
1790 block_state.flags.value |= SHARED_LOCOPS;
1791 } | T_ALL
1792 {
1793 if (conf_parser_ctx.pass == 2)
1794 block_state.flags.value = SHARED_ALL;
1795 };
1796
1797 /***************************************************************************
1798 * section cluster
1799 ***************************************************************************/
1800 cluster_entry: T_CLUSTER
1801 {
1802 if (conf_parser_ctx.pass != 2)
1803 break;
1804
1805 reset_block_state();
1806
1807 strlcpy(block_state.name.buf, "*", sizeof(block_state.name.buf));
1808 block_state.flags.value = SHARED_ALL;
1809 } '{' cluster_items '}' ';'
1810 {
1811 struct MaskItem *conf = NULL;
1812
1813 if (conf_parser_ctx.pass != 2)
1814 break;
1815
1816 conf = conf_make(CONF_CLUSTER);
1817 conf->flags = block_state.flags.value;
1818 conf->name = xstrdup(block_state.name.buf);
1819 };
1820
1821 cluster_items: cluster_items cluster_item | cluster_item;
1822 cluster_item: cluster_name | cluster_type | error ';' ;
1823
1824 cluster_name: NAME '=' QSTRING ';'
1825 {
1826 if (conf_parser_ctx.pass == 2)
1827 strlcpy(block_state.name.buf, yylval.string, sizeof(block_state.name.buf));
1828 };
1829
1830 cluster_type: TYPE
1831 {
1832 if (conf_parser_ctx.pass == 2)
1833 block_state.flags.value = 0;
1834 } '=' cluster_types ';' ;
1835
1836 cluster_types: cluster_types ',' cluster_type_item | cluster_type_item;
1837 cluster_type_item: KLINE
1838 {
1839 if (conf_parser_ctx.pass == 2)
1840 block_state.flags.value |= SHARED_KLINE;
1841 } | UNKLINE
1842 {
1843 if (conf_parser_ctx.pass == 2)
1844 block_state.flags.value |= SHARED_UNKLINE;
1845 } | T_DLINE
1846 {
1847 if (conf_parser_ctx.pass == 2)
1848 block_state.flags.value |= SHARED_DLINE;
1849 } | T_UNDLINE
1850 {
1851 if (conf_parser_ctx.pass == 2)
1852 block_state.flags.value |= SHARED_UNDLINE;
1853 } | XLINE
1854 {
1855 if (conf_parser_ctx.pass == 2)
1856 block_state.flags.value |= SHARED_XLINE;
1857 } | T_UNXLINE
1858 {
1859 if (conf_parser_ctx.pass == 2)
1860 block_state.flags.value |= SHARED_UNXLINE;
1861 } | RESV
1862 {
1863 if (conf_parser_ctx.pass == 2)
1864 block_state.flags.value |= SHARED_RESV;
1865 } | T_UNRESV
1866 {
1867 if (conf_parser_ctx.pass == 2)
1868 block_state.flags.value |= SHARED_UNRESV;
1869 } | T_LOCOPS
1870 {
1871 if (conf_parser_ctx.pass == 2)
1872 block_state.flags.value |= SHARED_LOCOPS;
1873 } | T_ALL
1874 {
1875 if (conf_parser_ctx.pass == 2)
1876 block_state.flags.value = SHARED_ALL;
1877 };
1878
1879 /***************************************************************************
1880 * section connect
1881 ***************************************************************************/
1882 connect_entry: CONNECT
1883 {
1884
1885 if (conf_parser_ctx.pass != 2)
1886 break;
1887
1888 reset_block_state();
1889 block_state.port.value = PORTNUM;
1890 } '{' connect_items '}' ';'
1891 {
1892 struct MaskItem *conf = NULL;
1893 struct addrinfo hints, *res;
1894
1895 if (conf_parser_ctx.pass != 2)
1896 break;
1897
1898 if (!block_state.name.buf[0] ||
1899 !block_state.host.buf[0])
1900 break;
1901
1902 if (!(block_state.rpass.buf[0] ||
1903 block_state.spass.buf[0]))
1904 break;
1905
1906 if (has_wildcards(block_state.name.buf) ||
1907 has_wildcards(block_state.host.buf))
1908 break;
1909
1910 conf = conf_make(CONF_SERVER);
1911 conf->port = block_state.port.value;
1912 conf->flags = block_state.flags.value;
1913 conf->aftype = block_state.aftype.value;
1914 conf->host = xstrdup(block_state.host.buf);
1915 conf->name = xstrdup(block_state.name.buf);
1916 conf->passwd = xstrdup(block_state.rpass.buf);
1917 conf->spasswd = xstrdup(block_state.spass.buf);
1918 conf->cipher_list = xstrdup(block_state.ciph.buf);
1919
1920 dlinkMoveList(&block_state.leaf.list, &conf->leaf_list);
1921 dlinkMoveList(&block_state.hub.list, &conf->hub_list);
1922
1923 if (block_state.bind.buf[0])
1924 {
1925 memset(&hints, 0, sizeof(hints));
1926
1927 hints.ai_family = AF_UNSPEC;
1928 hints.ai_socktype = SOCK_STREAM;
1929 hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST;
1930
1931 if (getaddrinfo(block_state.bind.buf, NULL, &hints, &res))
1932 ilog(LOG_TYPE_IRCD, "Invalid netmask for server vhost(%s)", block_state.bind.buf);
1933 else
1934 {
1935 assert(res != NULL);
1936
1937 memcpy(&conf->bind, res->ai_addr, res->ai_addrlen);
1938 conf->bind.ss.ss_family = res->ai_family;
1939 conf->bind.ss_len = res->ai_addrlen;
1940 freeaddrinfo(res);
1941 }
1942 }
1943
1944 conf_add_class_to_conf(conf, block_state.class.buf);
1945 lookup_confhost(conf);
1946 };
1947
1948 connect_items: connect_items connect_item | connect_item;
1949 connect_item: connect_name | connect_host | connect_vhost |
1950 connect_send_password | connect_accept_password |
1951 connect_aftype | connect_port | connect_ssl_cipher_list |
1952 connect_flags | connect_hub_mask | connect_leaf_mask |
1953 connect_class | connect_encrypted |
1954 error ';' ;
1955
1956 connect_name: NAME '=' QSTRING ';'
1957 {
1958 if (conf_parser_ctx.pass == 2)
1959 strlcpy(block_state.name.buf, yylval.string, sizeof(block_state.name.buf));
1960 };
1961
1962 connect_host: HOST '=' QSTRING ';'
1963 {
1964 if (conf_parser_ctx.pass == 2)
1965 strlcpy(block_state.host.buf, yylval.string, sizeof(block_state.host.buf));
1966 };
1967
1968 connect_vhost: VHOST '=' QSTRING ';'
1969 {
1970 if (conf_parser_ctx.pass == 2)
1971 strlcpy(block_state.bind.buf, yylval.string, sizeof(block_state.bind.buf));
1972 };
1973
1974 connect_send_password: SEND_PASSWORD '=' QSTRING ';'
1975 {
1976 if (conf_parser_ctx.pass != 2)
1977 break;
1978
1979 if ($3[0] == ':')
1980 yyerror("Server passwords cannot begin with a colon");
1981 else if (strchr($3, ' ') != NULL)
1982 yyerror("Server passwords cannot contain spaces");
1983 else
1984 strlcpy(block_state.spass.buf, yylval.string, sizeof(block_state.spass.buf));
1985 };
1986
1987 connect_accept_password: ACCEPT_PASSWORD '=' QSTRING ';'
1988 {
1989 if (conf_parser_ctx.pass != 2)
1990 break;
1991
1992 if ($3[0] == ':')
1993 yyerror("Server passwords cannot begin with a colon");
1994 else if (strchr($3, ' ') != NULL)
1995 yyerror("Server passwords cannot contain spaces");
1996 else
1997 strlcpy(block_state.rpass.buf, yylval.string, sizeof(block_state.rpass.buf));
1998 };
1999
2000 connect_port: PORT '=' NUMBER ';'
2001 {
2002 if (conf_parser_ctx.pass == 2)
2003 block_state.port.value = $3;
2004 };
2005
2006 connect_aftype: AFTYPE '=' T_IPV4 ';'
2007 {
2008 if (conf_parser_ctx.pass == 2)
2009 block_state.aftype.value = AF_INET;
2010 } | AFTYPE '=' T_IPV6 ';'
2011 {
2012 #ifdef IPV6
2013 if (conf_parser_ctx.pass == 2)
2014 block_state.aftype.value = AF_INET6;
2015 #endif
2016 };
2017
2018 connect_flags: IRCD_FLAGS
2019 {
2020 block_state.flags.value &= CONF_FLAGS_ENCRYPTED;
2021 } '=' connect_flags_items ';';
2022
2023 connect_flags_items: connect_flags_items ',' connect_flags_item | connect_flags_item;
2024 connect_flags_item: AUTOCONN
2025 {
2026 if (conf_parser_ctx.pass == 2)
2027 block_state.flags.value |= CONF_FLAGS_ALLOW_AUTO_CONN;
2028 } | T_SSL
2029 {
2030 if (conf_parser_ctx.pass == 2)
2031 block_state.flags.value |= CONF_FLAGS_SSL;
2032 };
2033
2034 connect_encrypted: ENCRYPTED '=' TBOOL ';'
2035 {
2036 if (conf_parser_ctx.pass == 2)
2037 {
2038 if (yylval.number)
2039 block_state.flags.value |= CONF_FLAGS_ENCRYPTED;
2040 else
2041 block_state.flags.value &= ~CONF_FLAGS_ENCRYPTED;
2042 }
2043 };
2044
2045 connect_hub_mask: HUB_MASK '=' QSTRING ';'
2046 {
2047 if (conf_parser_ctx.pass == 2)
2048 dlinkAdd(xstrdup(yylval.string), make_dlink_node(), &block_state.hub.list);
2049 };
2050
2051 connect_leaf_mask: LEAF_MASK '=' QSTRING ';'
2052 {
2053 if (conf_parser_ctx.pass == 2)
2054 dlinkAdd(xstrdup(yylval.string), make_dlink_node(), &block_state.leaf.list);
2055 };
2056
2057 connect_class: CLASS '=' QSTRING ';'
2058 {
2059 if (conf_parser_ctx.pass == 2)
2060 strlcpy(block_state.class.buf, yylval.string, sizeof(block_state.class.buf));
2061 };
2062
2063 connect_ssl_cipher_list: T_SSL_CIPHER_LIST '=' QSTRING ';'
2064 {
2065 #ifdef HAVE_LIBCRYPTO
2066 if (conf_parser_ctx.pass == 2)
2067 strlcpy(block_state.ciph.buf, yylval.string, sizeof(block_state.ciph.buf));
2068 #else
2069 if (conf_parser_ctx.pass == 2)
2070 yyerror("Ignoring connect::ciphers -- no OpenSSL support");
2071 #endif
2072 };
2073
2074
2075 /***************************************************************************
2076 * section kill
2077 ***************************************************************************/
2078 kill_entry: KILL
2079 {
2080 if (conf_parser_ctx.pass == 2)
2081 reset_block_state();
2082 } '{' kill_items '}' ';'
2083 {
2084 struct MaskItem *conf = NULL;
2085
2086 if (conf_parser_ctx.pass != 2)
2087 break;
2088
2089 if (!block_state.user.buf[0] ||
2090 !block_state.host.buf[0])
2091 break;
2092
2093
2094 if (block_state.port.value == 1)
2095 {
2096 #ifdef HAVE_LIBPCRE
2097 void *exp_user = NULL;
2098 void *exp_host = NULL;
2099 const char *errptr = NULL;
2100
2101 if (!(exp_user = ircd_pcre_compile(block_state.user.buf, &errptr)) ||
2102 !(exp_host = ircd_pcre_compile(block_state.host.buf, &errptr)))
2103 {
2104 ilog(LOG_TYPE_IRCD, "Failed to add regular expression based K-Line: %s",
2105 errptr);
2106 break;
2107 }
2108
2109 conf = conf_make(CONF_RKLINE);
2110 conf->regexuser = exp_user;
2111 conf->regexhost = exp_host;
2112
2113 conf->user = xstrdup(block_state.user.buf);
2114 conf->host = xstrdup(block_state.host.buf);
2115
2116 if (block_state.rpass.buf[0])
2117 conf->reason = xstrdup(block_state.rpass.buf);
2118 else
2119 conf->reason = xstrdup(CONF_NOREASON);
2120 #else
2121 ilog(LOG_TYPE_IRCD, "Failed to add regular expression based K-Line: no PCRE support");
2122 break;
2123 #endif
2124 }
2125 else
2126 {
2127 conf = conf_make(CONF_KLINE);
2128
2129 conf->user = xstrdup(block_state.user.buf);
2130 conf->host = xstrdup(block_state.host.buf);
2131
2132 if (block_state.rpass.buf[0])
2133 conf->reason = xstrdup(block_state.rpass.buf);
2134 else
2135 conf->reason = xstrdup(CONF_NOREASON);
2136 add_conf_by_address(CONF_KLINE, conf);
2137 }
2138 };
2139
2140 kill_type: TYPE
2141 {
2142 if (conf_parser_ctx.pass == 2)
2143 block_state.port.value = 0;
2144 } '=' kill_type_items ';';
2145
2146 kill_type_items: kill_type_items ',' kill_type_item | kill_type_item;
2147 kill_type_item: REGEX_T
2148 {
2149 if (conf_parser_ctx.pass == 2)
2150 block_state.port.value = 1;
2151 };
2152
2153 kill_items: kill_items kill_item | kill_item;
2154 kill_item: kill_user | kill_reason | kill_type | error;
2155
2156 kill_user: USER '=' QSTRING ';'
2157 {
2158
2159 if (conf_parser_ctx.pass == 2)
2160 {
2161 struct split_nuh_item nuh;
2162
2163 nuh.nuhmask = yylval.string;
2164 nuh.nickptr = NULL;
2165 nuh.userptr = block_state.user.buf;
2166 nuh.hostptr = block_state.host.buf;
2167
2168 nuh.nicksize = 0;
2169 nuh.usersize = sizeof(block_state.user.buf);
2170 nuh.hostsize = sizeof(block_state.host.buf);
2171
2172 split_nuh(&nuh);
2173 }
2174 };
2175
2176 kill_reason: REASON '=' QSTRING ';'
2177 {
2178 if (conf_parser_ctx.pass == 2)
2179 strlcpy(block_state.rpass.buf, yylval.string, sizeof(block_state.rpass.buf));
2180 };
2181
2182 /***************************************************************************
2183 * section deny
2184 ***************************************************************************/
2185 deny_entry: DENY
2186 {
2187 if (conf_parser_ctx.pass == 2)
2188 reset_block_state();
2189 } '{' deny_items '}' ';'
2190 {
2191 struct MaskItem *conf = NULL;
2192
2193 if (conf_parser_ctx.pass != 2)
2194 break;
2195
2196 if (!block_state.addr.buf[0])
2197 break;
2198
2199 if (parse_netmask(block_state.addr.buf, NULL, NULL) != HM_HOST)
2200 {
2201 conf = conf_make(CONF_DLINE);
2202 conf->host = xstrdup(block_state.addr.buf);
2203
2204 if (block_state.rpass.buf[0])
2205 conf->reason = xstrdup(block_state.rpass.buf);
2206 else
2207 conf->reason = xstrdup(CONF_NOREASON);
2208 add_conf_by_address(CONF_DLINE, conf);
2209 }
2210 };
2211
2212 deny_items: deny_items deny_item | deny_item;
2213 deny_item: deny_ip | deny_reason | error;
2214
2215 deny_ip: IP '=' QSTRING ';'
2216 {
2217 if (conf_parser_ctx.pass == 2)
2218 strlcpy(block_state.addr.buf, yylval.string, sizeof(block_state.addr.buf));
2219 };
2220
2221 deny_reason: REASON '=' QSTRING ';'
2222 {
2223 if (conf_parser_ctx.pass == 2)
2224 strlcpy(block_state.rpass.buf, yylval.string, sizeof(block_state.rpass.buf));
2225 };
2226
2227 /***************************************************************************
2228 * section exempt
2229 ***************************************************************************/
2230 exempt_entry: EXEMPT '{' exempt_items '}' ';';
2231
2232 exempt_items: exempt_items exempt_item | exempt_item;
2233 exempt_item: exempt_ip | error;
2234
2235 exempt_ip: IP '=' QSTRING ';'
2236 {
2237 if (conf_parser_ctx.pass == 2)
2238 {
2239 if (yylval.string[0] && parse_netmask(yylval.string, NULL, NULL) != HM_HOST)
2240 {
2241 struct MaskItem *conf = conf_make(CONF_EXEMPT);
2242 conf->host = xstrdup(yylval.string);
2243
2244 add_conf_by_address(CONF_EXEMPT, conf);
2245 }
2246 }
2247 };
2248
2249 /***************************************************************************
2250 * section gecos
2251 ***************************************************************************/
2252 gecos_entry: GECOS
2253 {
2254 if (conf_parser_ctx.pass == 2)
2255 reset_block_state();
2256 } '{' gecos_items '}' ';'
2257 {
2258 struct MaskItem *conf = NULL;
2259
2260 if (conf_parser_ctx.pass != 2)
2261 break;
2262
2263 if (!block_state.name.buf[0])
2264 break;
2265
2266 if (block_state.port.value == 1)
2267 {
2268 #ifdef HAVE_LIBPCRE
2269 void *exp_p = NULL;
2270 const char *errptr = NULL;
2271
2272 if (!(exp_p = ircd_pcre_compile(block_state.name.buf, &errptr)))
2273 {
2274 ilog(LOG_TYPE_IRCD, "Failed to add regular expression based X-Line: %s",
2275 errptr);
2276 break;
2277 }
2278
2279 conf = conf_make(CONF_RXLINE);
2280 conf->regexuser = exp_p;
2281 #else
2282 ilog(LOG_TYPE_IRCD, "Failed to add regular expression based X-Line: no PCRE support");
2283 break;
2284 #endif
2285 }
2286 else
2287 conf = conf_make(CONF_XLINE);
2288
2289 conf->name = xstrdup(block_state.name.buf);
2290
2291 if (block_state.rpass.buf[0])
2292 conf->reason = xstrdup(block_state.rpass.buf);
2293 else
2294 conf->reason = xstrdup(CONF_NOREASON);
2295 };
2296
2297 gecos_flags: TYPE
2298 {
2299 if (conf_parser_ctx.pass == 2)
2300 block_state.port.value = 0;
2301 } '=' gecos_flags_items ';';
2302
2303 gecos_flags_items: gecos_flags_items ',' gecos_flags_item | gecos_flags_item;
2304 gecos_flags_item: REGEX_T
2305 {
2306 if (conf_parser_ctx.pass == 2)
2307 block_state.port.value = 1;
2308 };
2309
2310 gecos_items: gecos_items gecos_item | gecos_item;
2311 gecos_item: gecos_name | gecos_reason | gecos_flags | error;
2312
2313 gecos_name: NAME '=' QSTRING ';'
2314 {
2315 if (conf_parser_ctx.pass == 2)
2316 strlcpy(block_state.name.buf, yylval.string, sizeof(block_state.name.buf));
2317 };
2318
2319 gecos_reason: REASON '=' QSTRING ';'
2320 {
2321 if (conf_parser_ctx.pass == 2)
2322 strlcpy(block_state.rpass.buf, yylval.string, sizeof(block_state.rpass.buf));
2323 };
2324
2325 /***************************************************************************
2326 * section general
2327 ***************************************************************************/
2328 general_entry: GENERAL
2329 '{' general_items '}' ';';
2330
2331 general_items: general_items general_item | general_item;
2332 general_item: general_hide_spoof_ips | general_ignore_bogus_ts |
2333 general_failed_oper_notice | general_anti_nick_flood |
2334 general_max_nick_time | general_max_nick_changes |
2335 general_max_accept | general_anti_spam_exit_message_time |
2336 general_ts_warn_delta | general_ts_max_delta |
2337 general_kill_chase_time_limit |
2338 general_invisible_on_connect |
2339 general_warn_no_nline | general_dots_in_ident |
2340 general_stats_o_oper_only | general_stats_k_oper_only |
2341 general_pace_wait | general_stats_i_oper_only |
2342 general_pace_wait_simple | general_stats_P_oper_only |
2343 general_short_motd | general_no_oper_flood |
2344 general_true_no_oper_flood | general_oper_pass_resv |
2345 general_message_locale |
2346 general_oper_only_umodes | general_max_targets |
2347 general_use_egd | general_egdpool_path |
2348 general_oper_umodes | general_caller_id_wait |
2349 general_opers_bypass_callerid | general_default_floodcount |
2350 general_min_nonwildcard | general_min_nonwildcard_simple |
2351 general_disable_remote_commands |
2352 general_throttle_time | general_havent_read_conf |
2353 general_ping_cookie |
2354 general_disable_auth |
2355 general_tkline_expire_notices | general_gline_enable |
2356 general_gline_duration | general_gline_request_duration |
2357 general_gline_min_cidr |
2358 general_gline_min_cidr6 |
2359 general_stats_e_disabled |
2360 general_max_watch | general_services_name |
2361 error;
2362
2363
2364 general_max_watch: MAX_WATCH '=' NUMBER ';'
2365 {
2366 ConfigFileEntry.max_watch = $3;
2367 };
2368
2369 general_gline_enable: GLINE_ENABLE '=' TBOOL ';'
2370 {
2371 if (conf_parser_ctx.pass == 2)
2372 ConfigFileEntry.glines = yylval.number;
2373 };
2374
2375 general_gline_duration: GLINE_DURATION '=' timespec ';'
2376 {
2377 if (conf_parser_ctx.pass == 2)
2378 ConfigFileEntry.gline_time = $3;
2379 };
2380
2381 general_gline_request_duration: GLINE_REQUEST_DURATION '=' timespec ';'
2382 {
2383 if (conf_parser_ctx.pass == 2)
2384 ConfigFileEntry.gline_request_time = $3;
2385 };
2386
2387 general_gline_min_cidr: GLINE_MIN_CIDR '=' NUMBER ';'
2388 {
2389 ConfigFileEntry.gline_min_cidr = $3;
2390 };
2391
2392 general_gline_min_cidr6: GLINE_MIN_CIDR6 '=' NUMBER ';'
2393 {
2394 ConfigFileEntry.gline_min_cidr6 = $3;
2395 };
2396
2397 general_tkline_expire_notices: TKLINE_EXPIRE_NOTICES '=' TBOOL ';'
2398 {
2399 ConfigFileEntry.tkline_expire_notices = yylval.number;
2400 };
2401
2402 general_kill_chase_time_limit: KILL_CHASE_TIME_LIMIT '=' timespec ';'
2403 {
2404 ConfigFileEntry.kill_chase_time_limit = $3;
2405 };
2406
2407 general_hide_spoof_ips: HIDE_SPOOF_IPS '=' TBOOL ';'
2408 {
2409 ConfigFileEntry.hide_spoof_ips = yylval.number;
2410 };
2411
2412 general_ignore_bogus_ts: IGNORE_BOGUS_TS '=' TBOOL ';'
2413 {
2414 ConfigFileEntry.ignore_bogus_ts = yylval.number;
2415 };
2416
2417 general_disable_remote_commands: DISABLE_REMOTE_COMMANDS '=' TBOOL ';'
2418 {
2419 ConfigFileEntry.disable_remote = yylval.number;
2420 };
2421
2422 general_failed_oper_notice: FAILED_OPER_NOTICE '=' TBOOL ';'
2423 {
2424 ConfigFileEntry.failed_oper_notice = yylval.number;
2425 };
2426
2427 general_anti_nick_flood: ANTI_NICK_FLOOD '=' TBOOL ';'
2428 {
2429 ConfigFileEntry.anti_nick_flood = yylval.number;
2430 };
2431
2432 general_max_nick_time: MAX_NICK_TIME '=' timespec ';'
2433 {
2434 ConfigFileEntry.max_nick_time = $3;
2435 };
2436
2437 general_max_nick_changes: MAX_NICK_CHANGES '=' NUMBER ';'
2438 {
2439 ConfigFileEntry.max_nick_changes = $3;
2440 };
2441
2442 general_max_accept: MAX_ACCEPT '=' NUMBER ';'
2443 {
2444 ConfigFileEntry.max_accept = $3;
2445 };
2446
2447 general_anti_spam_exit_message_time: ANTI_SPAM_EXIT_MESSAGE_TIME '=' timespec ';'
2448 {
2449 ConfigFileEntry.anti_spam_exit_message_time = $3;
2450 };
2451
2452 general_ts_warn_delta: TS_WARN_DELTA '=' timespec ';'
2453 {
2454 ConfigFileEntry.ts_warn_delta = $3;
2455 };
2456
2457 general_ts_max_delta: TS_MAX_DELTA '=' timespec ';'
2458 {
2459 if (conf_parser_ctx.pass == 2)
2460 ConfigFileEntry.ts_max_delta = $3;
2461 };
2462
2463 general_havent_read_conf: HAVENT_READ_CONF '=' NUMBER ';'
2464 {
2465 if (($3 > 0) && conf_parser_ctx.pass == 1)
2466 {
2467 ilog(LOG_TYPE_IRCD, "You haven't read your config file properly.");
2468 ilog(LOG_TYPE_IRCD, "There is a line in the example conf that will kill your server if not removed.");
2469 ilog(LOG_TYPE_IRCD, "Consider actually reading/editing the conf file, and removing this line.");
2470 exit(0);
2471 }
2472 };
2473
2474 general_invisible_on_connect: INVISIBLE_ON_CONNECT '=' TBOOL ';'
2475 {
2476 ConfigFileEntry.invisible_on_connect = yylval.number;
2477 };
2478
2479 general_warn_no_nline: WARN_NO_NLINE '=' TBOOL ';'
2480 {
2481 ConfigFileEntry.warn_no_nline = yylval.number;
2482 };
2483
2484 general_stats_e_disabled: STATS_E_DISABLED '=' TBOOL ';'
2485 {
2486 ConfigFileEntry.stats_e_disabled = yylval.number;
2487 };
2488
2489 general_stats_o_oper_only: STATS_O_OPER_ONLY '=' TBOOL ';'
2490 {
2491 ConfigFileEntry.stats_o_oper_only = yylval.number;
2492 };
2493
2494 general_stats_P_oper_only: STATS_P_OPER_ONLY '=' TBOOL ';'
2495 {
2496 ConfigFileEntry.stats_P_oper_only = yylval.number;
2497 };
2498
2499 general_stats_k_oper_only: STATS_K_OPER_ONLY '=' TBOOL ';'
2500 {
2501 ConfigFileEntry.stats_k_oper_only = 2 * yylval.number;
2502 } | STATS_K_OPER_ONLY '=' TMASKED ';'
2503 {
2504 ConfigFileEntry.stats_k_oper_only = 1;
2505 };
2506
2507 general_stats_i_oper_only: STATS_I_OPER_ONLY '=' TBOOL ';'
2508 {
2509 ConfigFileEntry.stats_i_oper_only = 2 * yylval.number;
2510 } | STATS_I_OPER_ONLY '=' TMASKED ';'
2511 {
2512 ConfigFileEntry.stats_i_oper_only = 1;
2513 };
2514
2515 general_pace_wait: PACE_WAIT '=' timespec ';'
2516 {
2517 ConfigFileEntry.pace_wait = $3;
2518 };
2519
2520 general_caller_id_wait: CALLER_ID_WAIT '=' timespec ';'
2521 {
2522 ConfigFileEntry.caller_id_wait = $3;
2523 };
2524
2525 general_opers_bypass_callerid: OPERS_BYPASS_CALLERID '=' TBOOL ';'
2526 {
2527 ConfigFileEntry.opers_bypass_callerid = yylval.number;
2528 };
2529
2530 general_pace_wait_simple: PACE_WAIT_SIMPLE '=' timespec ';'
2531 {
2532 ConfigFileEntry.pace_wait_simple = $3;
2533 };
2534
2535 general_short_motd: SHORT_MOTD '=' TBOOL ';'
2536 {
2537 ConfigFileEntry.short_motd = yylval.number;
2538 };
2539
2540 general_no_oper_flood: NO_OPER_FLOOD '=' TBOOL ';'
2541 {
2542 ConfigFileEntry.no_oper_flood = yylval.number;
2543 };
2544
2545 general_true_no_oper_flood: TRUE_NO_OPER_FLOOD '=' TBOOL ';'
2546 {
2547 ConfigFileEntry.true_no_oper_flood = yylval.number;
2548 };
2549
2550 general_oper_pass_resv: OPER_PASS_RESV '=' TBOOL ';'
2551 {
2552 ConfigFileEntry.oper_pass_resv = yylval.number;
2553 };
2554
2555 general_message_locale: MESSAGE_LOCALE '=' QSTRING ';'
2556 {
2557 if (conf_parser_ctx.pass == 2)
2558 {
2559 if (strlen(yylval.string) > LOCALE_LENGTH-2)
2560 yylval.string[LOCALE_LENGTH-1] = '\0';
2561
2562 set_locale(yylval.string);
2563 }
2564 };
2565
2566 general_dots_in_ident: DOTS_IN_IDENT '=' NUMBER ';'
2567 {
2568 ConfigFileEntry.dots_in_ident = $3;
2569 };
2570
2571 general_max_targets: MAX_TARGETS '=' NUMBER ';'
2572 {
2573 ConfigFileEntry.max_targets = $3;
2574 };
2575
2576 general_use_egd: USE_EGD '=' TBOOL ';'
2577 {
2578 ConfigFileEntry.use_egd = yylval.number;
2579 };
2580
2581 general_egdpool_path: EGDPOOL_PATH '=' QSTRING ';'
2582 {
2583 if (conf_parser_ctx.pass == 2)
2584 {
2585 MyFree(ConfigFileEntry.egdpool_path);
2586 ConfigFileEntry.egdpool_path = xstrdup(yylval.string);
2587 }
2588 };
2589
2590 general_services_name: T_SERVICES_NAME '=' QSTRING ';'
2591 {
2592 if (conf_parser_ctx.pass == 2 && valid_servname(yylval.string))
2593 {
2594 MyFree(ConfigFileEntry.service_name);
2595 ConfigFileEntry.service_name = xstrdup(yylval.string);
2596 }
2597 };
2598
2599 general_ping_cookie: PING_COOKIE '=' TBOOL ';'
2600 {
2601 ConfigFileEntry.ping_cookie = yylval.number;
2602 };
2603
2604 general_disable_auth: DISABLE_AUTH '=' TBOOL ';'
2605 {
2606 ConfigFileEntry.disable_auth = yylval.number;
2607 };
2608
2609 general_throttle_time: THROTTLE_TIME '=' timespec ';'
2610 {
2611 ConfigFileEntry.throttle_time = yylval.number;
2612 };
2613
2614 general_oper_umodes: OPER_UMODES
2615 {
2616 ConfigFileEntry.oper_umodes = 0;
2617 } '=' umode_oitems ';' ;
2618
2619 umode_oitems: umode_oitems ',' umode_oitem | umode_oitem;
2620 umode_oitem: T_BOTS
2621 {
2622 ConfigFileEntry.oper_umodes |= UMODE_BOTS;
2623 } | T_CCONN
2624 {
2625 ConfigFileEntry.oper_umodes |= UMODE_CCONN;
2626 } | T_CCONN_FULL
2627 {
2628 ConfigFileEntry.oper_umodes |= UMODE_CCONN_FULL;
2629 } | T_DEAF
2630 {
2631 ConfigFileEntry.oper_umodes |= UMODE_DEAF;
2632 } | T_DEBUG
2633 {
2634 ConfigFileEntry.oper_umodes |= UMODE_DEBUG;
2635 } | T_FULL
2636 {
2637 ConfigFileEntry.oper_umodes |= UMODE_FULL;
2638 } | HIDDEN
2639 {
2640 ConfigFileEntry.oper_umodes |= UMODE_HIDDEN;
2641 } | T_SKILL
2642 {
2643 ConfigFileEntry.oper_umodes |= UMODE_SKILL;
2644 } | T_NCHANGE
2645 {
2646 ConfigFileEntry.oper_umodes |= UMODE_NCHANGE;
2647 } | T_REJ
2648 {
2649 ConfigFileEntry.oper_umodes |= UMODE_REJ;
2650 } | T_UNAUTH
2651 {
2652 ConfigFileEntry.oper_umodes |= UMODE_UNAUTH;
2653 } | T_SPY
2654 {
2655 ConfigFileEntry.oper_umodes |= UMODE_SPY;
2656 } | T_EXTERNAL
2657 {
2658 ConfigFileEntry.oper_umodes |= UMODE_EXTERNAL;
2659 } | T_OPERWALL
2660 {
2661 ConfigFileEntry.oper_umodes |= UMODE_OPERWALL;
2662 } | T_SERVNOTICE
2663 {
2664 ConfigFileEntry.oper_umodes |= UMODE_SERVNOTICE;
2665 } | T_INVISIBLE
2666 {
2667 ConfigFileEntry.oper_umodes |= UMODE_INVISIBLE;
2668 } | T_WALLOP
2669 {
2670 ConfigFileEntry.oper_umodes |= UMODE_WALLOP;
2671 } | T_SOFTCALLERID
2672 {
2673 ConfigFileEntry.oper_umodes |= UMODE_SOFTCALLERID;
2674 } | T_CALLERID
2675 {
2676 ConfigFileEntry.oper_umodes |= UMODE_CALLERID;
2677 } | T_LOCOPS
2678 {
2679 ConfigFileEntry.oper_umodes |= UMODE_LOCOPS;
2680 };
2681
2682 general_oper_only_umodes: OPER_ONLY_UMODES
2683 {
2684 ConfigFileEntry.oper_only_umodes = 0;
2685 } '=' umode_items ';' ;
2686
2687 umode_items: umode_items ',' umode_item | umode_item;
2688 umode_item: T_BOTS
2689 {
2690 ConfigFileEntry.oper_only_umodes |= UMODE_BOTS;
2691 } | T_CCONN
2692 {
2693 ConfigFileEntry.oper_only_umodes |= UMODE_CCONN;
2694 } | T_CCONN_FULL
2695 {
2696 ConfigFileEntry.oper_only_umodes |= UMODE_CCONN_FULL;
2697 } | T_DEAF
2698 {
2699 ConfigFileEntry.oper_only_umodes |= UMODE_DEAF;
2700 } | T_DEBUG
2701 {
2702 ConfigFileEntry.oper_only_umodes |= UMODE_DEBUG;
2703 } | T_FULL
2704 {
2705 ConfigFileEntry.oper_only_umodes |= UMODE_FULL;
2706 } | T_SKILL
2707 {
2708 ConfigFileEntry.oper_only_umodes |= UMODE_SKILL;
2709 } | HIDDEN
2710 {
2711 ConfigFileEntry.oper_only_umodes |= UMODE_HIDDEN;
2712 } | T_NCHANGE
2713 {
2714 ConfigFileEntry.oper_only_umodes |= UMODE_NCHANGE;
2715 } | T_REJ
2716 {
2717 ConfigFileEntry.oper_only_umodes |= UMODE_REJ;
2718 } | T_UNAUTH
2719 {
2720 ConfigFileEntry.oper_only_umodes |= UMODE_UNAUTH;
2721 } | T_SPY
2722 {
2723 ConfigFileEntry.oper_only_umodes |= UMODE_SPY;
2724 } | T_EXTERNAL
2725 {
2726 ConfigFileEntry.oper_only_umodes |= UMODE_EXTERNAL;
2727 } | T_OPERWALL
2728 {
2729 ConfigFileEntry.oper_only_umodes |= UMODE_OPERWALL;
2730 } | T_SERVNOTICE
2731 {
2732 ConfigFileEntry.oper_only_umodes |= UMODE_SERVNOTICE;
2733 } | T_INVISIBLE
2734 {
2735 ConfigFileEntry.oper_only_umodes |= UMODE_INVISIBLE;
2736 } | T_WALLOP
2737 {
2738 ConfigFileEntry.oper_only_umodes |= UMODE_WALLOP;
2739 } | T_SOFTCALLERID
2740 {
2741 ConfigFileEntry.oper_only_umodes |= UMODE_SOFTCALLERID;
2742 } | T_CALLERID
2743 {
2744 ConfigFileEntry.oper_only_umodes |= UMODE_CALLERID;
2745 } | T_LOCOPS
2746 {
2747 ConfigFileEntry.oper_only_umodes |= UMODE_LOCOPS;
2748 };
2749
2750 general_min_nonwildcard: MIN_NONWILDCARD '=' NUMBER ';'
2751 {
2752 ConfigFileEntry.min_nonwildcard = $3;
2753 };
2754
2755 general_min_nonwildcard_simple: MIN_NONWILDCARD_SIMPLE '=' NUMBER ';'
2756 {
2757 ConfigFileEntry.min_nonwildcard_simple = $3;
2758 };
2759
2760 general_default_floodcount: DEFAULT_FLOODCOUNT '=' NUMBER ';'
2761 {
2762 ConfigFileEntry.default_floodcount = $3;
2763 };
2764
2765
2766 /***************************************************************************
2767 * section channel
2768 ***************************************************************************/
2769 channel_entry: CHANNEL
2770 '{' channel_items '}' ';';
2771
2772 channel_items: channel_items channel_item | channel_item;
2773 channel_item: channel_max_bans |
2774 channel_knock_delay | channel_knock_delay_channel |
2775 channel_max_chans_per_user | channel_max_chans_per_oper |
2776 channel_quiet_on_ban | channel_default_split_user_count |
2777 channel_default_split_server_count |
2778 channel_no_create_on_split | channel_restrict_channels |
2779 channel_no_join_on_split |
2780 channel_jflood_count | channel_jflood_time |
2781 channel_disable_fake_channels | error;
2782
2783 channel_disable_fake_channels: DISABLE_FAKE_CHANNELS '=' TBOOL ';'
2784 {
2785 ConfigChannel.disable_fake_channels = yylval.number;
2786 };
2787
2788 channel_restrict_channels: RESTRICT_CHANNELS '=' TBOOL ';'
2789 {
2790 ConfigChannel.restrict_channels = yylval.number;
2791 };
2792
2793 channel_knock_delay: KNOCK_DELAY '=' timespec ';'
2794 {
2795 ConfigChannel.knock_delay = $3;
2796 };
2797
2798 channel_knock_delay_channel: KNOCK_DELAY_CHANNEL '=' timespec ';'
2799 {
2800 ConfigChannel.knock_delay_channel = $3;
2801 };
2802
2803 channel_max_chans_per_user: MAX_CHANS_PER_USER '=' NUMBER ';'
2804 {
2805 ConfigChannel.max_chans_per_user = $3;
2806 };
2807
2808 channel_max_chans_per_oper: MAX_CHANS_PER_OPER '=' NUMBER ';'
2809 {
2810 ConfigChannel.max_chans_per_oper = $3;
2811 };
2812
2813 channel_quiet_on_ban: QUIET_ON_BAN '=' TBOOL ';'
2814 {
2815 ConfigChannel.quiet_on_ban = yylval.number;
2816 };
2817
2818 channel_max_bans: MAX_BANS '=' NUMBER ';'
2819 {
2820 ConfigChannel.max_bans = $3;
2821 };
2822
2823 channel_default_split_user_count: DEFAULT_SPLIT_USER_COUNT '=' NUMBER ';'
2824 {
2825 ConfigChannel.default_split_user_count = $3;
2826 };
2827
2828 channel_default_split_server_count: DEFAULT_SPLIT_SERVER_COUNT '=' NUMBER ';'
2829 {
2830 ConfigChannel.default_split_server_count = $3;
2831 };
2832
2833 channel_no_create_on_split: NO_CREATE_ON_SPLIT '=' TBOOL ';'
2834 {
2835 ConfigChannel.no_create_on_split = yylval.number;
2836 };
2837
2838 channel_no_join_on_split: NO_JOIN_ON_SPLIT '=' TBOOL ';'
2839 {
2840 ConfigChannel.no_join_on_split = yylval.number;
2841 };
2842
2843 channel_jflood_count: JOIN_FLOOD_COUNT '=' NUMBER ';'
2844 {
2845 GlobalSetOptions.joinfloodcount = yylval.number;
2846 };
2847
2848 channel_jflood_time: JOIN_FLOOD_TIME '=' timespec ';'
2849 {
2850 GlobalSetOptions.joinfloodtime = yylval.number;
2851 };
2852
2853 /***************************************************************************
2854 * section serverhide
2855 ***************************************************************************/
2856 serverhide_entry: SERVERHIDE
2857 '{' serverhide_items '}' ';';
2858
2859 serverhide_items: serverhide_items serverhide_item | serverhide_item;
2860 serverhide_item: serverhide_flatten_links | serverhide_hide_servers |
2861 serverhide_links_delay |
2862 serverhide_hidden | serverhide_hidden_name |
2863 serverhide_hide_server_ips |
2864 error;
2865
2866 serverhide_flatten_links: FLATTEN_LINKS '=' TBOOL ';'
2867 {
2868 if (conf_parser_ctx.pass == 2)
2869 ConfigServerHide.flatten_links = yylval.number;
2870 };
2871
2872 serverhide_hide_servers: HIDE_SERVERS '=' TBOOL ';'
2873 {
2874 if (conf_parser_ctx.pass == 2)
2875 ConfigServerHide.hide_servers = yylval.number;
2876 };
2877
2878 serverhide_hidden_name: HIDDEN_NAME '=' QSTRING ';'
2879 {
2880 if (conf_parser_ctx.pass == 2)
2881 {
2882 MyFree(ConfigServerHide.hidden_name);
2883 ConfigServerHide.hidden_name = xstrdup(yylval.string);
2884 }
2885 };
2886
2887 serverhide_links_delay: LINKS_DELAY '=' timespec ';'
2888 {
2889 if (conf_parser_ctx.pass == 2)
2890 {
2891 if (($3 > 0) && ConfigServerHide.links_disabled == 1)
2892 {
2893 eventAddIsh("write_links_file", write_links_file, NULL, $3);
2894 ConfigServerHide.links_disabled = 0;
2895 }
2896
2897 ConfigServerHide.links_delay = $3;
2898 }
2899 };
2900
2901 serverhide_hidden: HIDDEN '=' TBOOL ';'
2902 {
2903 if (conf_parser_ctx.pass == 2)
2904 ConfigServerHide.hidden = yylval.number;
2905 };
2906
2907 serverhide_hide_server_ips: HIDE_SERVER_IPS '=' TBOOL ';'
2908 {
2909 if (conf_parser_ctx.pass == 2)
2910 ConfigServerHide.hide_server_ips = yylval.number;
2911 };

Properties

Name Value
svn:eol-style native
svn:keywords Id Revision