ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/src/conf_parser.y
Revision: 2228
Committed: Thu Jun 13 19:46:30 2013 UTC (12 years, 2 months ago) by michael
File size: 74432 byte(s)
Log Message:
- Implement certificate fingerprint validation for oper{} and connect{} blocks.
  Some code taken from oftc-hybrid. Hello, stu!

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

Properties

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