ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/src/conf_parser.y
Revision: 967
Committed: Sun Aug 2 18:05:28 2009 UTC (16 years ago) by michael
Original Path: ircd-hybrid-7.2/src/ircd_parser.y
File size: 94526 byte(s)
Log Message:
- added ssl_server_protocol configuration option to servinfo{}.
  valid flags are 'sslv3' and 'tlsv1'

File Contents

# Content
1 /*
2 * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd).
3 * ircd_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 "stdinc.h"
32 #include "ircd.h"
33 #include "tools.h"
34 #include "list.h"
35 #include "s_conf.h"
36 #include "event.h"
37 #include "s_log.h"
38 #include "client.h" /* for UMODE_ALL only */
39 #include "pcre.h"
40 #include "irc_string.h"
41 #include "irc_getaddrinfo.h"
42 #include "sprintf_irc.h"
43 #include "memory.h"
44 #include "modules.h"
45 #include "s_serv.h"
46 #include "hostmask.h"
47 #include "send.h"
48 #include "listener.h"
49 #include "resv.h"
50 #include "numeric.h"
51 #include "s_user.h"
52
53 #ifdef HAVE_LIBCRYPTO
54 #include <openssl/rsa.h>
55 #include <openssl/bio.h>
56 #include <openssl/pem.h>
57 #endif
58
59 static char *class_name = NULL;
60 static struct ConfItem *yy_conf = NULL;
61 static struct AccessItem *yy_aconf = NULL;
62 static struct MatchItem *yy_match_item = NULL;
63 static struct ClassItem *yy_class = NULL;
64 static char *yy_class_name = NULL;
65
66 static dlink_list col_conf_list = { NULL, NULL, 0 };
67 static dlink_list hub_conf_list = { NULL, NULL, 0 };
68 static dlink_list leaf_conf_list = { NULL, NULL, 0 };
69 static unsigned int listener_flags = 0;
70 static unsigned int regex_ban = 0;
71 static char userbuf[IRCD_BUFSIZE];
72 static char hostbuf[IRCD_BUFSIZE];
73 static char reasonbuf[REASONLEN + 1];
74 static char gecos_name[REALLEN * 4];
75
76 extern dlink_list gdeny_items; /* XXX */
77
78 static char *resv_reason = NULL;
79 static char *listener_address = NULL;
80 static int not_atom = 0;
81
82 struct CollectItem
83 {
84 dlink_node node;
85 char *name;
86 char *user;
87 char *host;
88 char *passwd;
89 int port;
90 int flags;
91 #ifdef HAVE_LIBCRYPTO
92 char *rsa_public_key_file;
93 RSA *rsa_public_key;
94 #endif
95 };
96
97 static void
98 free_collect_item(struct CollectItem *item)
99 {
100 MyFree(item->name);
101 MyFree(item->user);
102 MyFree(item->host);
103 MyFree(item->passwd);
104 #ifdef HAVE_LIBCRYPTO
105 MyFree(item->rsa_public_key_file);
106 #endif
107 MyFree(item);
108 }
109
110 static void
111 unhook_hub_leaf_confs(void)
112 {
113 dlink_node *ptr;
114 dlink_node *next_ptr;
115 struct CollectItem *yy_hconf;
116 struct CollectItem *yy_lconf;
117
118 DLINK_FOREACH_SAFE(ptr, next_ptr, hub_conf_list.head)
119 {
120 yy_hconf = ptr->data;
121 dlinkDelete(&yy_hconf->node, &hub_conf_list);
122 free_collect_item(yy_hconf);
123 }
124
125 DLINK_FOREACH_SAFE(ptr, next_ptr, leaf_conf_list.head)
126 {
127 yy_lconf = ptr->data;
128 dlinkDelete(&yy_lconf->node, &leaf_conf_list);
129 free_collect_item(yy_lconf);
130 }
131 }
132
133 %}
134
135 %union {
136 int number;
137 char *string;
138 }
139
140 %token ACCEPT_PASSWORD
141 %token ACTION
142 %token ADMIN
143 %token AFTYPE
144 %token T_ALLOW
145 %token ANTI_NICK_FLOOD
146 %token ANTI_SPAM_EXIT_MESSAGE_TIME
147 %token AUTOCONN
148 %token T_BLOCK
149 %token BURST_AWAY
150 %token BURST_TOPICWHO
151 %token BYTES KBYTES MBYTES GBYTES TBYTES
152 %token CALLER_ID_WAIT
153 %token CAN_FLOOD
154 %token CAN_IDLE
155 %token CHANNEL
156 %token CIDR_BITLEN_IPV4
157 %token CIDR_BITLEN_IPV6
158 %token CIPHER_PREFERENCE
159 %token CLASS
160 %token COMPRESSED
161 %token COMPRESSION_LEVEL
162 %token CONNECT
163 %token CONNECTFREQ
164 %token CRYPTLINK
165 %token DEFAULT_CIPHER_PREFERENCE
166 %token DEFAULT_FLOODCOUNT
167 %token DEFAULT_SPLIT_SERVER_COUNT
168 %token DEFAULT_SPLIT_USER_COUNT
169 %token DENY
170 %token DESCRIPTION
171 %token DIE
172 %token DISABLE_AUTH
173 %token DISABLE_FAKE_CHANNELS
174 %token DISABLE_HIDDEN
175 %token DISABLE_LOCAL_CHANNELS
176 %token DISABLE_REMOTE_COMMANDS
177 %token DOT_IN_IP6_ADDR
178 %token DOTS_IN_IDENT
179 %token DURATION
180 %token EGDPOOL_PATH
181 %token EMAIL
182 %token ENABLE
183 %token ENCRYPTED
184 %token EXCEED_LIMIT
185 %token EXEMPT
186 %token FAILED_OPER_NOTICE
187 %token FAKENAME
188 %token IRCD_FLAGS
189 %token FLATTEN_LINKS
190 %token FFAILED_OPERLOG
191 %token FKILLLOG
192 %token FKLINELOG
193 %token FGLINELOG
194 %token FIOERRLOG
195 %token FOPERLOG
196 %token FOPERSPYLOG
197 %token FUSERLOG
198 %token GECOS
199 %token GENERAL
200 %token GLINE
201 %token GLINES
202 %token GLINE_EXEMPT
203 %token GLINE_LOG
204 %token GLINE_TIME
205 %token GLINE_MIN_CIDR
206 %token GLINE_MIN_CIDR6
207 %token GLOBAL_KILL
208 %token IRCD_AUTH
209 %token NEED_IDENT
210 %token HAVENT_READ_CONF
211 %token HIDDEN
212 %token HIDDEN_ADMIN
213 %token HIDDEN_NAME
214 %token HIDDEN_OPER
215 %token HIDE_SERVER_IPS
216 %token HIDE_SERVERS
217 %token HIDE_SPOOF_IPS
218 %token HOST
219 %token HUB
220 %token HUB_MASK
221 %token IDLETIME
222 %token IGNORE_BOGUS_TS
223 %token INVISIBLE_ON_CONNECT
224 %token IP
225 %token KILL
226 %token KILL_CHASE_TIME_LIMIT
227 %token KLINE
228 %token KLINE_EXEMPT
229 %token KLINE_REASON
230 %token KLINE_WITH_REASON
231 %token KNOCK_DELAY
232 %token KNOCK_DELAY_CHANNEL
233 %token LEAF_MASK
234 %token LINKS_DELAY
235 %token LISTEN
236 %token T_LOG
237 %token LOGGING
238 %token LOG_LEVEL
239 %token MAX_ACCEPT
240 %token MAX_BANS
241 %token MAX_CHANS_PER_USER
242 %token MAX_GLOBAL
243 %token MAX_IDENT
244 %token MAX_LOCAL
245 %token MAX_NICK_CHANGES
246 %token MAX_NICK_TIME
247 %token MAX_NUMBER
248 %token MAX_TARGETS
249 %token MAX_WATCH
250 %token MESSAGE_LOCALE
251 %token MIN_NONWILDCARD
252 %token MIN_NONWILDCARD_SIMPLE
253 %token MODULE
254 %token MODULES
255 %token NAME
256 %token NEED_PASSWORD
257 %token NETWORK_DESC
258 %token NETWORK_NAME
259 %token NICK
260 %token NICK_CHANGES
261 %token NO_CREATE_ON_SPLIT
262 %token NO_JOIN_ON_SPLIT
263 %token NO_OPER_FLOOD
264 %token NO_TILDE
265 %token NOT
266 %token NUMBER
267 %token NUMBER_PER_IDENT
268 %token NUMBER_PER_CIDR
269 %token NUMBER_PER_IP
270 %token NUMBER_PER_IP_GLOBAL
271 %token OPERATOR
272 %token OPERS_BYPASS_CALLERID
273 %token OPER_LOG
274 %token OPER_ONLY_UMODES
275 %token OPER_PASS_RESV
276 %token OPER_SPY_T
277 %token OPER_UMODES
278 %token JOIN_FLOOD_COUNT
279 %token JOIN_FLOOD_TIME
280 %token PACE_WAIT
281 %token PACE_WAIT_SIMPLE
282 %token PASSWORD
283 %token PATH
284 %token PING_COOKIE
285 %token PING_TIME
286 %token PING_WARNING
287 %token PORT
288 %token QSTRING
289 %token QUIET_ON_BAN
290 %token REASON
291 %token REDIRPORT
292 %token REDIRSERV
293 %token REGEX_T
294 %token REHASH
295 %token TREJECT_HOLD_TIME
296 %token REMOTE
297 %token REMOTEBAN
298 %token RESTRICT_CHANNELS
299 %token RESTRICTED
300 %token RSA_PRIVATE_KEY_FILE
301 %token RSA_PUBLIC_KEY_FILE
302 %token SSL_CERTIFICATE_FILE
303 %token T_SSL_CONNECTION_METHOD
304 %token T_SSLV3
305 %token T_TLSV1
306 %token RESV
307 %token RESV_EXEMPT
308 %token SECONDS MINUTES HOURS DAYS WEEKS
309 %token SENDQ
310 %token SEND_PASSWORD
311 %token SERVERHIDE
312 %token SERVERINFO
313 %token SERVLINK_PATH
314 %token IRCD_SID
315 %token TKLINE_EXPIRE_NOTICES
316 %token T_SHARED
317 %token T_CLUSTER
318 %token TYPE
319 %token SHORT_MOTD
320 %token SILENT
321 %token SPOOF
322 %token SPOOF_NOTICE
323 %token STATS_E_DISABLED
324 %token STATS_I_OPER_ONLY
325 %token STATS_K_OPER_ONLY
326 %token STATS_O_OPER_ONLY
327 %token STATS_P_OPER_ONLY
328 %token TBOOL
329 %token TMASKED
330 %token T_REJECT
331 %token TS_MAX_DELTA
332 %token TS_WARN_DELTA
333 %token TWODOTS
334 %token T_ALL
335 %token T_BOTS
336 %token T_SOFTCALLERID
337 %token T_CALLERID
338 %token T_CCONN
339 %token T_CCONN_FULL
340 %token T_CLIENT_FLOOD
341 %token T_DEAF
342 %token T_DEBUG
343 %token T_DRONE
344 %token T_EXTERNAL
345 %token T_FULL
346 %token T_INVISIBLE
347 %token T_IPV4
348 %token T_IPV6
349 %token T_LOCOPS
350 %token T_LOGPATH
351 %token T_L_CRIT
352 %token T_L_DEBUG
353 %token T_L_ERROR
354 %token T_L_INFO
355 %token T_L_NOTICE
356 %token T_L_TRACE
357 %token T_L_WARN
358 %token T_MAX_CLIENTS
359 %token T_NCHANGE
360 %token T_OPERWALL
361 %token T_REJ
362 %token T_SERVER
363 %token T_SERVNOTICE
364 %token T_SKILL
365 %token T_SPY
366 %token T_SSL
367 %token T_UMODES
368 %token T_UNAUTH
369 %token T_UNRESV
370 %token T_UNXLINE
371 %token T_WALLOP
372 %token THROTTLE_TIME
373 %token TOPICBURST
374 %token TRUE_NO_OPER_FLOOD
375 %token TKLINE
376 %token TXLINE
377 %token TRESV
378 %token UNKLINE
379 %token USER
380 %token USE_EGD
381 %token USE_EXCEPT
382 %token USE_INVEX
383 %token USE_KNOCK
384 %token USE_LOGGING
385 %token USE_WHOIS_ACTUALLY
386 %token VHOST
387 %token VHOST6
388 %token XLINE
389 %token WARN
390 %token WARN_NO_NLINE
391
392 %type <string> QSTRING
393 %type <number> NUMBER
394 %type <number> timespec
395 %type <number> timespec_
396 %type <number> sizespec
397 %type <number> sizespec_
398
399 %%
400 conf:
401 | conf conf_item
402 ;
403
404 conf_item: admin_entry
405 | logging_entry
406 | oper_entry
407 | channel_entry
408 | class_entry
409 | listen_entry
410 | auth_entry
411 | serverinfo_entry
412 | serverhide_entry
413 | resv_entry
414 | shared_entry
415 | cluster_entry
416 | connect_entry
417 | kill_entry
418 | deny_entry
419 | exempt_entry
420 | general_entry
421 | gline_entry
422 | gecos_entry
423 | modules_entry
424 | error ';'
425 | error '}'
426 ;
427
428
429 timespec_: { $$ = 0; } | timespec;
430 timespec: NUMBER timespec_
431 {
432 $$ = $1 + $2;
433 }
434 | NUMBER SECONDS timespec_
435 {
436 $$ = $1 + $3;
437 }
438 | NUMBER MINUTES timespec_
439 {
440 $$ = $1 * 60 + $3;
441 }
442 | NUMBER HOURS timespec_
443 {
444 $$ = $1 * 60 * 60 + $3;
445 }
446 | NUMBER DAYS timespec_
447 {
448 $$ = $1 * 60 * 60 * 24 + $3;
449 }
450 | NUMBER WEEKS timespec_
451 {
452 $$ = $1 * 60 * 60 * 24 * 7 + $3;
453 }
454 ;
455
456 sizespec_: { $$ = 0; } | sizespec;
457 sizespec: NUMBER sizespec_ { $$ = $1 + $2; }
458 | NUMBER BYTES sizespec_ { $$ = $1 + $3; }
459 | NUMBER KBYTES sizespec_ { $$ = $1 * 1024 + $3; }
460 | NUMBER MBYTES sizespec_ { $$ = $1 * 1024 * 1024 + $3; }
461 ;
462
463
464 /***************************************************************************
465 * section modules
466 ***************************************************************************/
467 modules_entry: MODULES
468 '{' modules_items '}' ';';
469
470 modules_items: modules_items modules_item | modules_item;
471 modules_item: modules_module | modules_path | error ';' ;
472
473 modules_module: MODULE '=' QSTRING ';'
474 {
475 #ifndef STATIC_MODULES /* NOOP in the static case */
476 if (conf_parser_ctx.pass == 2)
477 {
478 char *m_bn;
479
480 m_bn = basename(yylval.string);
481
482 /* I suppose we should just ignore it if it is already loaded(since
483 * otherwise we would flood the opers on rehash) -A1kmm.
484 */
485 add_conf_module(yylval.string);
486 }
487 #endif
488 };
489
490 modules_path: PATH '=' QSTRING ';'
491 {
492 #ifndef STATIC_MODULES
493 if (conf_parser_ctx.pass == 2)
494 mod_add_path(yylval.string);
495 #endif
496 };
497
498
499 serverinfo_entry: SERVERINFO '{' serverinfo_items '}' ';';
500
501 serverinfo_items: serverinfo_items serverinfo_item | serverinfo_item ;
502 serverinfo_item: serverinfo_name | serverinfo_vhost |
503 serverinfo_hub | serverinfo_description |
504 serverinfo_network_name | serverinfo_network_desc |
505 serverinfo_max_clients |
506 serverinfo_rsa_private_key_file | serverinfo_vhost6 |
507 serverinfo_sid | serverinfo_ssl_certificate_file |
508 serverinfo_ssl_connection_method |
509 error ';' ;
510
511
512 serverinfo_ssl_connection_method: T_SSL_CONNECTION_METHOD
513 {
514 if (conf_parser_ctx.boot && conf_parser_ctx.pass == 2)
515 ServerInfo.tls_version = 0;
516 } '=' method_types ';'
517 {
518 if (conf_parser_ctx.boot && conf_parser_ctx.pass == 2)
519 {
520 if (!(ServerInfo.tls_version & CONF_SERVER_INFO_TLS_VERSION_SSLV3))
521 SSL_CTX_set_options(ServerInfo.server_ctx, SSL_OP_NO_SSLv3);
522 if (!(ServerInfo.tls_version & CONF_SERVER_INFO_TLS_VERSION_TLSV1))
523 SSL_CTX_set_options(ServerInfo.server_ctx, SSL_OP_NO_TLSv1);
524 }
525 };
526
527 method_types: method_types ',' method_type_item | method_type_item;
528 method_type_item: T_SSLV3
529 {
530 if (conf_parser_ctx.boot && conf_parser_ctx.pass == 2)
531 ServerInfo.tls_version |= CONF_SERVER_INFO_TLS_VERSION_SSLV3;
532 } | T_TLSV1
533 {
534 if (conf_parser_ctx.boot && conf_parser_ctx.pass == 2)
535 ServerInfo.tls_version |= CONF_SERVER_INFO_TLS_VERSION_TLSV1;
536 };
537
538 serverinfo_ssl_certificate_file: SSL_CERTIFICATE_FILE '=' QSTRING ';'
539 {
540 #ifdef HAVE_LIBCRYPTO
541 if (conf_parser_ctx.pass == 2 && ServerInfo.server_ctx)
542 {
543 if (!ServerInfo.rsa_private_key_file)
544 {
545 yyerror("No rsa_private_key_file specified, SSL disabled");
546 break;
547 }
548
549 if (SSL_CTX_use_certificate_file(ServerInfo.server_ctx, yylval.string,
550 SSL_FILETYPE_PEM) <= 0)
551 {
552 yyerror(ERR_lib_error_string(ERR_get_error()));
553 break;
554 }
555
556 if (SSL_CTX_use_PrivateKey_file(ServerInfo.server_ctx, ServerInfo.rsa_private_key_file,
557 SSL_FILETYPE_PEM) <= 0)
558 {
559 yyerror(ERR_lib_error_string(ERR_get_error()));
560 break;
561 }
562
563 if (!SSL_CTX_check_private_key(ServerInfo.server_ctx))
564 {
565 yyerror(ERR_lib_error_string(ERR_get_error()));
566 break;
567 }
568 }
569 #endif
570 };
571
572 serverinfo_rsa_private_key_file: RSA_PRIVATE_KEY_FILE '=' QSTRING ';'
573 {
574 #ifdef HAVE_LIBCRYPTO
575 if (conf_parser_ctx.pass == 1)
576 {
577 BIO *file;
578
579 if (ServerInfo.rsa_private_key)
580 {
581 RSA_free(ServerInfo.rsa_private_key);
582 ServerInfo.rsa_private_key = NULL;
583 }
584
585 if (ServerInfo.rsa_private_key_file)
586 {
587 MyFree(ServerInfo.rsa_private_key_file);
588 ServerInfo.rsa_private_key_file = NULL;
589 }
590
591 DupString(ServerInfo.rsa_private_key_file, yylval.string);
592
593 if ((file = BIO_new_file(yylval.string, "r")) == NULL)
594 {
595 yyerror("File open failed, ignoring");
596 break;
597 }
598
599 ServerInfo.rsa_private_key = (RSA *)PEM_read_bio_RSAPrivateKey(file, NULL,
600 0, NULL);
601
602 BIO_set_close(file, BIO_CLOSE);
603 BIO_free(file);
604
605 if (ServerInfo.rsa_private_key == NULL)
606 {
607 yyerror("Couldn't extract key, ignoring");
608 break;
609 }
610
611 if (!RSA_check_key(ServerInfo.rsa_private_key))
612 {
613 RSA_free(ServerInfo.rsa_private_key);
614 ServerInfo.rsa_private_key = NULL;
615
616 yyerror("Invalid key, ignoring");
617 break;
618 }
619
620 /* require 2048 bit (256 byte) key */
621 if (RSA_size(ServerInfo.rsa_private_key) != 256)
622 {
623 RSA_free(ServerInfo.rsa_private_key);
624 ServerInfo.rsa_private_key = NULL;
625
626 yyerror("Not a 2048 bit key, ignoring");
627 }
628 }
629 #endif
630 };
631
632 serverinfo_name: NAME '=' QSTRING ';'
633 {
634 /* this isn't rehashable */
635 if (conf_parser_ctx.pass == 2)
636 {
637 if (ServerInfo.name == NULL)
638 {
639 /* the ircd will exit() in main() if we dont set one */
640 if (strlen(yylval.string) <= HOSTLEN)
641 DupString(ServerInfo.name, yylval.string);
642 }
643 }
644 };
645
646 serverinfo_sid: IRCD_SID '=' QSTRING ';'
647 {
648 /* this isn't rehashable */
649 if (conf_parser_ctx.pass == 2 && !ServerInfo.sid)
650 {
651 if (valid_sid(yylval.string))
652 DupString(ServerInfo.sid, yylval.string);
653 else
654 {
655 ilog(L_ERROR, "Ignoring config file entry SID -- invalid SID. Aborting.");
656 exit(0);
657 }
658 }
659 };
660
661 serverinfo_description: DESCRIPTION '=' QSTRING ';'
662 {
663 if (conf_parser_ctx.pass == 2)
664 {
665 MyFree(ServerInfo.description);
666 DupString(ServerInfo.description,yylval.string);
667 }
668 };
669
670 serverinfo_network_name: NETWORK_NAME '=' QSTRING ';'
671 {
672 if (conf_parser_ctx.pass == 2)
673 {
674 char *p;
675
676 if ((p = strchr(yylval.string, ' ')) != NULL)
677 p = '\0';
678
679 MyFree(ServerInfo.network_name);
680 DupString(ServerInfo.network_name, yylval.string);
681 }
682 };
683
684 serverinfo_network_desc: NETWORK_DESC '=' QSTRING ';'
685 {
686 if (conf_parser_ctx.pass == 2)
687 {
688 MyFree(ServerInfo.network_desc);
689 DupString(ServerInfo.network_desc, yylval.string);
690 }
691 };
692
693 serverinfo_vhost: VHOST '=' QSTRING ';'
694 {
695 if (conf_parser_ctx.pass == 2 && *yylval.string != '*')
696 {
697 struct addrinfo hints, *res;
698
699 memset(&hints, 0, sizeof(hints));
700
701 hints.ai_family = AF_UNSPEC;
702 hints.ai_socktype = SOCK_STREAM;
703 hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST;
704
705 if (irc_getaddrinfo(yylval.string, NULL, &hints, &res))
706 ilog(L_ERROR, "Invalid netmask for server vhost(%s)", yylval.string);
707 else
708 {
709 assert(res != NULL);
710
711 memcpy(&ServerInfo.ip, res->ai_addr, res->ai_addrlen);
712 ServerInfo.ip.ss.ss_family = res->ai_family;
713 ServerInfo.ip.ss_len = res->ai_addrlen;
714 irc_freeaddrinfo(res);
715
716 ServerInfo.specific_ipv4_vhost = 1;
717 }
718 }
719 };
720
721 serverinfo_vhost6: VHOST6 '=' QSTRING ';'
722 {
723 #ifdef IPV6
724 if (conf_parser_ctx.pass == 2 && *yylval.string != '*')
725 {
726 struct addrinfo hints, *res;
727
728 memset(&hints, 0, sizeof(hints));
729
730 hints.ai_family = AF_UNSPEC;
731 hints.ai_socktype = SOCK_STREAM;
732 hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST;
733
734 if (irc_getaddrinfo(yylval.string, NULL, &hints, &res))
735 ilog(L_ERROR, "Invalid netmask for server vhost6(%s)", yylval.string);
736 else
737 {
738 assert(res != NULL);
739
740 memcpy(&ServerInfo.ip6, res->ai_addr, res->ai_addrlen);
741 ServerInfo.ip6.ss.ss_family = res->ai_family;
742 ServerInfo.ip6.ss_len = res->ai_addrlen;
743 irc_freeaddrinfo(res);
744
745 ServerInfo.specific_ipv6_vhost = 1;
746 }
747 }
748 #endif
749 };
750
751 serverinfo_max_clients: T_MAX_CLIENTS '=' NUMBER ';'
752 {
753 if (conf_parser_ctx.pass == 2)
754 {
755 recalc_fdlimit(NULL);
756
757 if ($3 < MAXCLIENTS_MIN)
758 {
759 char buf[IRCD_BUFSIZE];
760 ircsprintf(buf, "MAXCLIENTS too low, setting to %d", MAXCLIENTS_MIN);
761 yyerror(buf);
762 }
763 else if ($3 > MAXCLIENTS_MAX)
764 {
765 char buf[IRCD_BUFSIZE];
766 ircsprintf(buf, "MAXCLIENTS too high, setting to %d", MAXCLIENTS_MAX);
767 yyerror(buf);
768 }
769 else
770 ServerInfo.max_clients = $3;
771 }
772 };
773
774 serverinfo_hub: HUB '=' TBOOL ';'
775 {
776 if (conf_parser_ctx.pass == 2)
777 {
778 if (yylval.number)
779 {
780 ServerInfo.hub = 1;
781 delete_capability("HUB");
782 add_capability("HUB", CAP_HUB, 1);
783 }
784 else if (ServerInfo.hub)
785 {
786
787 ServerInfo.hub = 0;
788 delete_capability("HUB");
789 }
790 }
791 };
792
793 /***************************************************************************
794 * admin section
795 ***************************************************************************/
796 admin_entry: ADMIN '{' admin_items '}' ';' ;
797
798 admin_items: admin_items admin_item | admin_item;
799 admin_item: admin_name | admin_description |
800 admin_email | error ';' ;
801
802 admin_name: NAME '=' QSTRING ';'
803 {
804 if (conf_parser_ctx.pass == 2)
805 {
806 MyFree(AdminInfo.name);
807 DupString(AdminInfo.name, yylval.string);
808 }
809 };
810
811 admin_email: EMAIL '=' QSTRING ';'
812 {
813 if (conf_parser_ctx.pass == 2)
814 {
815 MyFree(AdminInfo.email);
816 DupString(AdminInfo.email, yylval.string);
817 }
818 };
819
820 admin_description: DESCRIPTION '=' QSTRING ';'
821 {
822 if (conf_parser_ctx.pass == 2)
823 {
824 MyFree(AdminInfo.description);
825 DupString(AdminInfo.description, yylval.string);
826 }
827 };
828
829 /***************************************************************************
830 * section logging
831 ***************************************************************************/
832 /* XXX */
833 logging_entry: LOGGING '{' logging_items '}' ';' ;
834
835 logging_items: logging_items logging_item |
836 logging_item ;
837
838 logging_item: logging_path | logging_oper_log |
839 logging_log_level |
840 logging_use_logging | logging_fuserlog |
841 logging_foperlog | logging_fglinelog |
842 logging_fklinelog | logging_killlog |
843 logging_foperspylog | logging_ioerrlog |
844 logging_ffailed_operlog |
845 error ';' ;
846
847 logging_path: T_LOGPATH '=' QSTRING ';'
848 {
849 };
850
851 logging_oper_log: OPER_LOG '=' QSTRING ';'
852 {
853 };
854
855 logging_fuserlog: FUSERLOG '=' QSTRING ';'
856 {
857 if (conf_parser_ctx.pass == 2)
858 strlcpy(ConfigLoggingEntry.userlog, yylval.string,
859 sizeof(ConfigLoggingEntry.userlog));
860 };
861
862 logging_ffailed_operlog: FFAILED_OPERLOG '=' QSTRING ';'
863 {
864 if (conf_parser_ctx.pass == 2)
865 strlcpy(ConfigLoggingEntry.failed_operlog, yylval.string,
866 sizeof(ConfigLoggingEntry.failed_operlog));
867 };
868
869 logging_foperlog: FOPERLOG '=' QSTRING ';'
870 {
871 if (conf_parser_ctx.pass == 2)
872 strlcpy(ConfigLoggingEntry.operlog, yylval.string,
873 sizeof(ConfigLoggingEntry.operlog));
874 };
875
876 logging_foperspylog: FOPERSPYLOG '=' QSTRING ';'
877 {
878 if (conf_parser_ctx.pass == 2)
879 strlcpy(ConfigLoggingEntry.operspylog, yylval.string,
880 sizeof(ConfigLoggingEntry.operspylog));
881 };
882
883 logging_fglinelog: FGLINELOG '=' QSTRING ';'
884 {
885 if (conf_parser_ctx.pass == 2)
886 strlcpy(ConfigLoggingEntry.glinelog, yylval.string,
887 sizeof(ConfigLoggingEntry.glinelog));
888 };
889
890 logging_fklinelog: FKLINELOG '=' QSTRING ';'
891 {
892 if (conf_parser_ctx.pass == 2)
893 strlcpy(ConfigLoggingEntry.klinelog, yylval.string,
894 sizeof(ConfigLoggingEntry.klinelog));
895 };
896
897 logging_ioerrlog: FIOERRLOG '=' QSTRING ';'
898 {
899 if (conf_parser_ctx.pass == 2)
900 strlcpy(ConfigLoggingEntry.ioerrlog, yylval.string,
901 sizeof(ConfigLoggingEntry.ioerrlog));
902 };
903
904 logging_killlog: FKILLLOG '=' QSTRING ';'
905 {
906 if (conf_parser_ctx.pass == 2)
907 strlcpy(ConfigLoggingEntry.killlog, yylval.string,
908 sizeof(ConfigLoggingEntry.killlog));
909 };
910
911 logging_log_level: LOG_LEVEL '=' T_L_CRIT ';'
912 {
913 if (conf_parser_ctx.pass == 2)
914 set_log_level(L_CRIT);
915 } | LOG_LEVEL '=' T_L_ERROR ';'
916 {
917 if (conf_parser_ctx.pass == 2)
918 set_log_level(L_ERROR);
919 } | LOG_LEVEL '=' T_L_WARN ';'
920 {
921 if (conf_parser_ctx.pass == 2)
922 set_log_level(L_WARN);
923 } | LOG_LEVEL '=' T_L_NOTICE ';'
924 {
925 if (conf_parser_ctx.pass == 2)
926 set_log_level(L_NOTICE);
927 } | LOG_LEVEL '=' T_L_TRACE ';'
928 {
929 if (conf_parser_ctx.pass == 2)
930 set_log_level(L_TRACE);
931 } | LOG_LEVEL '=' T_L_INFO ';'
932 {
933 if (conf_parser_ctx.pass == 2)
934 set_log_level(L_INFO);
935 } | LOG_LEVEL '=' T_L_DEBUG ';'
936 {
937 if (conf_parser_ctx.pass == 2)
938 set_log_level(L_DEBUG);
939 };
940
941 logging_use_logging: USE_LOGGING '=' TBOOL ';'
942 {
943 if (conf_parser_ctx.pass == 2)
944 ConfigLoggingEntry.use_logging = yylval.number;
945 };
946
947 /***************************************************************************
948 * section oper
949 ***************************************************************************/
950 oper_entry: OPERATOR
951 {
952 if (conf_parser_ctx.pass == 2)
953 {
954 yy_conf = make_conf_item(OPER_TYPE);
955 yy_aconf = map_to_conf(yy_conf);
956 SetConfEncrypted(yy_aconf); /* Yes, the default is encrypted */
957 }
958 else
959 {
960 MyFree(class_name);
961 class_name = NULL;
962 }
963 } oper_name_b '{' oper_items '}' ';'
964 {
965 if (conf_parser_ctx.pass == 2)
966 {
967 struct CollectItem *yy_tmp;
968 dlink_node *ptr;
969 dlink_node *next_ptr;
970
971 conf_add_class_to_conf(yy_conf, class_name);
972
973 /* Now, make sure there is a copy of the "base" given oper
974 * block in each of the collected copies
975 */
976
977 DLINK_FOREACH_SAFE(ptr, next_ptr, col_conf_list.head)
978 {
979 struct AccessItem *new_aconf;
980 struct ConfItem *new_conf;
981 yy_tmp = ptr->data;
982
983 new_conf = make_conf_item(OPER_TYPE);
984 new_aconf = (struct AccessItem *)map_to_conf(new_conf);
985
986 new_aconf->flags = yy_aconf->flags;
987
988 if (yy_conf->name != NULL)
989 DupString(new_conf->name, yy_conf->name);
990 if (yy_tmp->user != NULL)
991 DupString(new_aconf->user, yy_tmp->user);
992 else
993 DupString(new_aconf->user, "*");
994 if (yy_tmp->host != NULL)
995 DupString(new_aconf->host, yy_tmp->host);
996 else
997 DupString(new_aconf->host, "*");
998 conf_add_class_to_conf(new_conf, class_name);
999 if (yy_aconf->passwd != NULL)
1000 DupString(new_aconf->passwd, yy_aconf->passwd);
1001
1002 new_aconf->port = yy_aconf->port;
1003 #ifdef HAVE_LIBCRYPTO
1004 if (yy_aconf->rsa_public_key_file != NULL)
1005 {
1006 BIO *file;
1007
1008 DupString(new_aconf->rsa_public_key_file,
1009 yy_aconf->rsa_public_key_file);
1010
1011 file = BIO_new_file(yy_aconf->rsa_public_key_file, "r");
1012 new_aconf->rsa_public_key = (RSA *)PEM_read_bio_RSA_PUBKEY(file,
1013 NULL, 0, NULL);
1014 BIO_set_close(file, BIO_CLOSE);
1015 BIO_free(file);
1016 }
1017 #endif
1018
1019 #ifdef HAVE_LIBCRYPTO
1020 if (yy_tmp->name && (yy_tmp->passwd || yy_aconf->rsa_public_key)
1021 && yy_tmp->host)
1022 #else
1023 if (yy_tmp->name && yy_tmp->passwd && yy_tmp->host)
1024 #endif
1025 {
1026 conf_add_class_to_conf(new_conf, class_name);
1027 if (yy_tmp->name != NULL)
1028 DupString(new_conf->name, yy_tmp->name);
1029 }
1030
1031 dlinkDelete(&yy_tmp->node, &col_conf_list);
1032 free_collect_item(yy_tmp);
1033 }
1034
1035 yy_conf = NULL;
1036 yy_aconf = NULL;
1037
1038
1039 MyFree(class_name);
1040 class_name = NULL;
1041 }
1042 };
1043
1044 oper_name_b: | oper_name_t;
1045 oper_items: oper_items oper_item | oper_item;
1046 oper_item: oper_name | oper_user | oper_password | oper_hidden_admin |
1047 oper_hidden_oper | oper_umodes |
1048 oper_class | oper_global_kill | oper_remote |
1049 oper_kline | oper_xline | oper_unkline |
1050 oper_gline | oper_nick_changes | oper_remoteban |
1051 oper_die | oper_rehash | oper_admin | oper_operwall |
1052 oper_encrypted | oper_rsa_public_key_file |
1053 oper_flags | error ';' ;
1054
1055 oper_name: NAME '=' QSTRING ';'
1056 {
1057 if (conf_parser_ctx.pass == 2)
1058 {
1059 if (strlen(yylval.string) > OPERNICKLEN)
1060 yylval.string[OPERNICKLEN] = '\0';
1061
1062 MyFree(yy_conf->name);
1063 DupString(yy_conf->name, yylval.string);
1064 }
1065 };
1066
1067 oper_name_t: QSTRING
1068 {
1069 if (conf_parser_ctx.pass == 2)
1070 {
1071 if (strlen(yylval.string) > OPERNICKLEN)
1072 yylval.string[OPERNICKLEN] = '\0';
1073
1074 MyFree(yy_conf->name);
1075 DupString(yy_conf->name, yylval.string);
1076 }
1077 };
1078
1079 oper_user: USER '=' QSTRING ';'
1080 {
1081 if (conf_parser_ctx.pass == 2)
1082 {
1083 struct split_nuh_item nuh;
1084
1085 nuh.nuhmask = yylval.string;
1086 nuh.nickptr = NULL;
1087 nuh.userptr = userbuf;
1088 nuh.hostptr = hostbuf;
1089
1090 nuh.nicksize = 0;
1091 nuh.usersize = sizeof(userbuf);
1092 nuh.hostsize = sizeof(hostbuf);
1093
1094 split_nuh(&nuh);
1095
1096 if (yy_aconf->user == NULL)
1097 {
1098 DupString(yy_aconf->user, userbuf);
1099 DupString(yy_aconf->host, hostbuf);
1100 }
1101 else
1102 {
1103 struct CollectItem *yy_tmp = MyMalloc(sizeof(struct CollectItem));
1104
1105 DupString(yy_tmp->user, userbuf);
1106 DupString(yy_tmp->host, hostbuf);
1107
1108 dlinkAdd(yy_tmp, &yy_tmp->node, &col_conf_list);
1109 }
1110 }
1111 };
1112
1113 oper_password: PASSWORD '=' QSTRING ';'
1114 {
1115 if (conf_parser_ctx.pass == 2)
1116 {
1117 if (yy_aconf->passwd != NULL)
1118 memset(yy_aconf->passwd, 0, strlen(yy_aconf->passwd));
1119
1120 MyFree(yy_aconf->passwd);
1121 DupString(yy_aconf->passwd, yylval.string);
1122 }
1123 };
1124
1125 oper_encrypted: ENCRYPTED '=' TBOOL ';'
1126 {
1127 if (conf_parser_ctx.pass == 2)
1128 {
1129 if (yylval.number)
1130 SetConfEncrypted(yy_aconf);
1131 else
1132 ClearConfEncrypted(yy_aconf);
1133 }
1134 };
1135
1136 oper_rsa_public_key_file: RSA_PUBLIC_KEY_FILE '=' QSTRING ';'
1137 {
1138 #ifdef HAVE_LIBCRYPTO
1139 if (conf_parser_ctx.pass == 2)
1140 {
1141 BIO *file;
1142
1143 if (yy_aconf->rsa_public_key != NULL)
1144 {
1145 RSA_free(yy_aconf->rsa_public_key);
1146 yy_aconf->rsa_public_key = NULL;
1147 }
1148
1149 if (yy_aconf->rsa_public_key_file != NULL)
1150 {
1151 MyFree(yy_aconf->rsa_public_key_file);
1152 yy_aconf->rsa_public_key_file = NULL;
1153 }
1154
1155 DupString(yy_aconf->rsa_public_key_file, yylval.string);
1156 file = BIO_new_file(yylval.string, "r");
1157
1158 if (file == NULL)
1159 {
1160 yyerror("Ignoring rsa_public_key_file -- file doesn't exist");
1161 break;
1162 }
1163
1164 yy_aconf->rsa_public_key = (RSA *)PEM_read_bio_RSA_PUBKEY(file, NULL, 0, NULL);
1165
1166 if (yy_aconf->rsa_public_key == NULL)
1167 {
1168 yyerror("Ignoring rsa_public_key_file -- Key invalid; check key syntax.");
1169 break;
1170 }
1171
1172 BIO_set_close(file, BIO_CLOSE);
1173 BIO_free(file);
1174 }
1175 #endif /* HAVE_LIBCRYPTO */
1176 };
1177
1178 oper_class: CLASS '=' QSTRING ';'
1179 {
1180 if (conf_parser_ctx.pass == 2)
1181 {
1182 MyFree(class_name);
1183 DupString(class_name, yylval.string);
1184 }
1185 };
1186
1187 oper_umodes: T_UMODES
1188 {
1189 if (conf_parser_ctx.pass == 2)
1190 yy_aconf->modes = 0;
1191 } '=' oper_umodes_items ';' ;
1192
1193 oper_umodes_items: oper_umodes_items ',' oper_umodes_item | oper_umodes_item;
1194 oper_umodes_item: T_BOTS
1195 {
1196 if (conf_parser_ctx.pass == 2)
1197 yy_aconf->modes |= UMODE_BOTS;
1198 } | T_CCONN
1199 {
1200 if (conf_parser_ctx.pass == 2)
1201 yy_aconf->modes |= UMODE_CCONN;
1202 } | T_CCONN_FULL
1203 {
1204 if (conf_parser_ctx.pass == 2)
1205 yy_aconf->modes |= UMODE_CCONN_FULL;
1206 } | T_DEAF
1207 {
1208 if (conf_parser_ctx.pass == 2)
1209 yy_aconf->modes |= UMODE_DEAF;
1210 } | T_DEBUG
1211 {
1212 if (conf_parser_ctx.pass == 2)
1213 yy_aconf->modes |= UMODE_DEBUG;
1214 } | T_FULL
1215 {
1216 if (conf_parser_ctx.pass == 2)
1217 yy_aconf->modes |= UMODE_FULL;
1218 } | T_SKILL
1219 {
1220 if (conf_parser_ctx.pass == 2)
1221 yy_aconf->modes |= UMODE_SKILL;
1222 } | T_NCHANGE
1223 {
1224 if (conf_parser_ctx.pass == 2)
1225 yy_aconf->modes |= UMODE_NCHANGE;
1226 } | T_REJ
1227 {
1228 if (conf_parser_ctx.pass == 2)
1229 yy_aconf->modes |= UMODE_REJ;
1230 } | T_UNAUTH
1231 {
1232 if (conf_parser_ctx.pass == 2)
1233 yy_aconf->modes |= UMODE_UNAUTH;
1234 } | T_SPY
1235 {
1236 if (conf_parser_ctx.pass == 2)
1237 yy_aconf->modes |= UMODE_SPY;
1238 } | T_EXTERNAL
1239 {
1240 if (conf_parser_ctx.pass == 2)
1241 yy_aconf->modes |= UMODE_EXTERNAL;
1242 } | T_OPERWALL
1243 {
1244 if (conf_parser_ctx.pass == 2)
1245 yy_aconf->modes |= UMODE_OPERWALL;
1246 } | T_SERVNOTICE
1247 {
1248 if (conf_parser_ctx.pass == 2)
1249 yy_aconf->modes |= UMODE_SERVNOTICE;
1250 } | T_INVISIBLE
1251 {
1252 if (conf_parser_ctx.pass == 2)
1253 yy_aconf->modes |= UMODE_INVISIBLE;
1254 } | T_WALLOP
1255 {
1256 if (conf_parser_ctx.pass == 2)
1257 yy_aconf->modes |= UMODE_WALLOP;
1258 } | T_SOFTCALLERID
1259 {
1260 if (conf_parser_ctx.pass == 2)
1261 yy_aconf->modes |= UMODE_SOFTCALLERID;
1262 } | T_CALLERID
1263 {
1264 if (conf_parser_ctx.pass == 2)
1265 yy_aconf->modes |= UMODE_CALLERID;
1266 } | T_LOCOPS
1267 {
1268 if (conf_parser_ctx.pass == 2)
1269 yy_aconf->modes |= UMODE_LOCOPS;
1270 };
1271
1272 oper_global_kill: GLOBAL_KILL '=' TBOOL ';'
1273 {
1274 if (conf_parser_ctx.pass == 2)
1275 {
1276 if (yylval.number)
1277 yy_aconf->port |= OPER_FLAG_GLOBAL_KILL;
1278 else
1279 yy_aconf->port &= ~OPER_FLAG_GLOBAL_KILL;
1280 }
1281 };
1282
1283 oper_remote: REMOTE '=' TBOOL ';'
1284 {
1285 if (conf_parser_ctx.pass == 2)
1286 {
1287 if (yylval.number)
1288 yy_aconf->port |= OPER_FLAG_REMOTE;
1289 else
1290 yy_aconf->port &= ~OPER_FLAG_REMOTE;
1291 }
1292 };
1293
1294 oper_remoteban: REMOTEBAN '=' TBOOL ';'
1295 {
1296 if (conf_parser_ctx.pass == 2)
1297 {
1298 if (yylval.number)
1299 yy_aconf->port |= OPER_FLAG_REMOTEBAN;
1300 else
1301 yy_aconf->port &= ~OPER_FLAG_REMOTEBAN;
1302 }
1303 };
1304
1305 oper_kline: KLINE '=' TBOOL ';'
1306 {
1307 if (conf_parser_ctx.pass == 2)
1308 {
1309 if (yylval.number)
1310 yy_aconf->port |= OPER_FLAG_K;
1311 else
1312 yy_aconf->port &= ~OPER_FLAG_K;
1313 }
1314 };
1315
1316 oper_xline: XLINE '=' TBOOL ';'
1317 {
1318 if (conf_parser_ctx.pass == 2)
1319 {
1320 if (yylval.number)
1321 yy_aconf->port |= OPER_FLAG_X;
1322 else
1323 yy_aconf->port &= ~OPER_FLAG_X;
1324 }
1325 };
1326
1327 oper_unkline: UNKLINE '=' TBOOL ';'
1328 {
1329 if (conf_parser_ctx.pass == 2)
1330 {
1331 if (yylval.number)
1332 yy_aconf->port |= OPER_FLAG_UNKLINE;
1333 else
1334 yy_aconf->port &= ~OPER_FLAG_UNKLINE;
1335 }
1336 };
1337
1338 oper_gline: GLINE '=' TBOOL ';'
1339 {
1340 if (conf_parser_ctx.pass == 2)
1341 {
1342 if (yylval.number)
1343 yy_aconf->port |= OPER_FLAG_GLINE;
1344 else
1345 yy_aconf->port &= ~OPER_FLAG_GLINE;
1346 }
1347 };
1348
1349 oper_nick_changes: NICK_CHANGES '=' TBOOL ';'
1350 {
1351 if (conf_parser_ctx.pass == 2)
1352 {
1353 if (yylval.number)
1354 yy_aconf->port |= OPER_FLAG_N;
1355 else
1356 yy_aconf->port &= ~OPER_FLAG_N;
1357 }
1358 };
1359
1360 oper_die: DIE '=' TBOOL ';'
1361 {
1362 if (conf_parser_ctx.pass == 2)
1363 {
1364 if (yylval.number)
1365 yy_aconf->port |= OPER_FLAG_DIE;
1366 else
1367 yy_aconf->port &= ~OPER_FLAG_DIE;
1368 }
1369 };
1370
1371 oper_rehash: REHASH '=' TBOOL ';'
1372 {
1373 if (conf_parser_ctx.pass == 2)
1374 {
1375 if (yylval.number)
1376 yy_aconf->port |= OPER_FLAG_REHASH;
1377 else
1378 yy_aconf->port &= ~OPER_FLAG_REHASH;
1379 }
1380 };
1381
1382 oper_admin: ADMIN '=' TBOOL ';'
1383 {
1384 if (conf_parser_ctx.pass == 2)
1385 {
1386 if (yylval.number)
1387 yy_aconf->port |= OPER_FLAG_ADMIN;
1388 else
1389 yy_aconf->port &= ~OPER_FLAG_ADMIN;
1390 }
1391 };
1392
1393 oper_hidden_admin: HIDDEN_ADMIN '=' TBOOL ';'
1394 {
1395 if (conf_parser_ctx.pass == 2)
1396 {
1397 if (yylval.number)
1398 yy_aconf->port |= OPER_FLAG_HIDDEN_ADMIN;
1399 else
1400 yy_aconf->port &= ~OPER_FLAG_HIDDEN_ADMIN;
1401 }
1402 };
1403
1404 oper_hidden_oper: HIDDEN_OPER '=' TBOOL ';'
1405 {
1406 if (conf_parser_ctx.pass == 2)
1407 {
1408 if (yylval.number)
1409 yy_aconf->port |= OPER_FLAG_HIDDEN_OPER;
1410 else
1411 yy_aconf->port &= ~OPER_FLAG_HIDDEN_OPER;
1412 }
1413 };
1414
1415 oper_operwall: T_OPERWALL '=' TBOOL ';'
1416 {
1417 if (conf_parser_ctx.pass == 2)
1418 {
1419 if (yylval.number)
1420 yy_aconf->port |= OPER_FLAG_OPERWALL;
1421 else
1422 yy_aconf->port &= ~OPER_FLAG_OPERWALL;
1423 }
1424 };
1425
1426 oper_flags: IRCD_FLAGS
1427 {
1428 } '=' oper_flags_items ';';
1429
1430 oper_flags_items: oper_flags_items ',' oper_flags_item | oper_flags_item;
1431 oper_flags_item: NOT { not_atom = 1; } oper_flags_item_atom
1432 | { not_atom = 0; } oper_flags_item_atom;
1433
1434 oper_flags_item_atom: GLOBAL_KILL
1435 {
1436 if (conf_parser_ctx.pass == 2)
1437 {
1438 if (not_atom)yy_aconf->port &= ~OPER_FLAG_GLOBAL_KILL;
1439 else yy_aconf->port |= OPER_FLAG_GLOBAL_KILL;
1440 }
1441 } | REMOTE
1442 {
1443 if (conf_parser_ctx.pass == 2)
1444 {
1445 if (not_atom) yy_aconf->port &= ~OPER_FLAG_REMOTE;
1446 else yy_aconf->port |= OPER_FLAG_REMOTE;
1447 }
1448 } | KLINE
1449 {
1450 if (conf_parser_ctx.pass == 2)
1451 {
1452 if (not_atom) yy_aconf->port &= ~OPER_FLAG_K;
1453 else yy_aconf->port |= OPER_FLAG_K;
1454 }
1455 } | UNKLINE
1456 {
1457 if (conf_parser_ctx.pass == 2)
1458 {
1459 if (not_atom) yy_aconf->port &= ~OPER_FLAG_UNKLINE;
1460 else yy_aconf->port |= OPER_FLAG_UNKLINE;
1461 }
1462 } | XLINE
1463 {
1464 if (conf_parser_ctx.pass == 2)
1465 {
1466 if (not_atom) yy_aconf->port &= ~OPER_FLAG_X;
1467 else yy_aconf->port |= OPER_FLAG_X;
1468 }
1469 } | GLINE
1470 {
1471 if (conf_parser_ctx.pass == 2)
1472 {
1473 if (not_atom) yy_aconf->port &= ~OPER_FLAG_GLINE;
1474 else yy_aconf->port |= OPER_FLAG_GLINE;
1475 }
1476 } | DIE
1477 {
1478 if (conf_parser_ctx.pass == 2)
1479 {
1480 if (not_atom) yy_aconf->port &= ~OPER_FLAG_DIE;
1481 else yy_aconf->port |= OPER_FLAG_DIE;
1482 }
1483 } | REHASH
1484 {
1485 if (conf_parser_ctx.pass == 2)
1486 {
1487 if (not_atom) yy_aconf->port &= ~OPER_FLAG_REHASH;
1488 else yy_aconf->port |= OPER_FLAG_REHASH;
1489 }
1490 } | ADMIN
1491 {
1492 if (conf_parser_ctx.pass == 2)
1493 {
1494 if (not_atom) yy_aconf->port &= ~OPER_FLAG_ADMIN;
1495 else yy_aconf->port |= OPER_FLAG_ADMIN;
1496 }
1497 } | HIDDEN_ADMIN
1498 {
1499 if (conf_parser_ctx.pass == 2)
1500 {
1501 if (not_atom) yy_aconf->port &= ~OPER_FLAG_HIDDEN_ADMIN;
1502 else yy_aconf->port |= OPER_FLAG_HIDDEN_ADMIN;
1503 }
1504 } | NICK_CHANGES
1505 {
1506 if (conf_parser_ctx.pass == 2)
1507 {
1508 if (not_atom) yy_aconf->port &= ~OPER_FLAG_N;
1509 else yy_aconf->port |= OPER_FLAG_N;
1510 }
1511 } | T_OPERWALL
1512 {
1513 if (conf_parser_ctx.pass == 2)
1514 {
1515 if (not_atom) yy_aconf->port &= ~OPER_FLAG_OPERWALL;
1516 else yy_aconf->port |= OPER_FLAG_OPERWALL;
1517 }
1518 } | OPER_SPY_T
1519 {
1520 if (conf_parser_ctx.pass == 2)
1521 {
1522 if (not_atom) yy_aconf->port &= ~OPER_FLAG_OPER_SPY;
1523 else yy_aconf->port |= OPER_FLAG_OPER_SPY;
1524 }
1525 } | HIDDEN_OPER
1526 {
1527 if (conf_parser_ctx.pass == 2)
1528 {
1529 if (not_atom) yy_aconf->port &= ~OPER_FLAG_HIDDEN_OPER;
1530 else yy_aconf->port |= OPER_FLAG_HIDDEN_OPER;
1531 }
1532 } | REMOTEBAN
1533 {
1534 if (conf_parser_ctx.pass == 2)
1535 {
1536 if (not_atom) yy_aconf->port &= ~OPER_FLAG_REMOTEBAN;
1537 else yy_aconf->port |= OPER_FLAG_REMOTEBAN;
1538 }
1539 } | ENCRYPTED
1540 {
1541 if (conf_parser_ctx.pass == 2)
1542 {
1543 if (not_atom) ClearConfEncrypted(yy_aconf);
1544 else SetConfEncrypted(yy_aconf);
1545 }
1546 };
1547
1548
1549 /***************************************************************************
1550 * section class
1551 ***************************************************************************/
1552 class_entry: CLASS
1553 {
1554 if (conf_parser_ctx.pass == 1)
1555 {
1556 yy_conf = make_conf_item(CLASS_TYPE);
1557 yy_class = map_to_conf(yy_conf);
1558 }
1559 } class_name_b '{' class_items '}' ';'
1560 {
1561 if (conf_parser_ctx.pass == 1)
1562 {
1563 struct ConfItem *cconf = NULL;
1564 struct ClassItem *class = NULL;
1565
1566 if (yy_class_name == NULL)
1567 delete_conf_item(yy_conf);
1568 else
1569 {
1570 cconf = find_exact_name_conf(CLASS_TYPE, yy_class_name, NULL, NULL);
1571
1572 if (cconf != NULL) /* The class existed already */
1573 {
1574 int user_count = 0;
1575
1576 rebuild_cidr_class(cconf, yy_class);
1577
1578 class = map_to_conf(cconf);
1579
1580 user_count = class->curr_user_count;
1581 memcpy(class, yy_class, sizeof(*class));
1582 class->curr_user_count = user_count;
1583 class->active = 1;
1584
1585 delete_conf_item(yy_conf);
1586
1587 MyFree(cconf->name); /* Allows case change of class name */
1588 cconf->name = yy_class_name;
1589 }
1590 else /* Brand new class */
1591 {
1592 MyFree(yy_conf->name); /* just in case it was allocated */
1593 yy_conf->name = yy_class_name;
1594 yy_class->active = 1;
1595 }
1596 }
1597
1598 yy_class_name = NULL;
1599 }
1600 };
1601
1602 class_name_b: | class_name_t;
1603
1604 class_items: class_items class_item | class_item;
1605 class_item: class_name |
1606 class_cidr_bitlen_ipv4 | class_cidr_bitlen_ipv6 |
1607 class_ping_time |
1608 class_ping_warning |
1609 class_number_per_cidr |
1610 class_number_per_ip |
1611 class_connectfreq |
1612 class_max_number |
1613 class_max_global |
1614 class_max_local |
1615 class_max_ident |
1616 class_sendq |
1617 error ';' ;
1618
1619 class_name: NAME '=' QSTRING ';'
1620 {
1621 if (conf_parser_ctx.pass == 1)
1622 {
1623 MyFree(yy_class_name);
1624 DupString(yy_class_name, yylval.string);
1625 }
1626 };
1627
1628 class_name_t: QSTRING
1629 {
1630 if (conf_parser_ctx.pass == 1)
1631 {
1632 MyFree(yy_class_name);
1633 DupString(yy_class_name, yylval.string);
1634 }
1635 };
1636
1637 class_ping_time: PING_TIME '=' timespec ';'
1638 {
1639 if (conf_parser_ctx.pass == 1)
1640 PingFreq(yy_class) = $3;
1641 };
1642
1643 class_ping_warning: PING_WARNING '=' timespec ';'
1644 {
1645 if (conf_parser_ctx.pass == 1)
1646 PingWarning(yy_class) = $3;
1647 };
1648
1649 class_number_per_ip: NUMBER_PER_IP '=' NUMBER ';'
1650 {
1651 if (conf_parser_ctx.pass == 1)
1652 MaxPerIp(yy_class) = $3;
1653 };
1654
1655 class_connectfreq: CONNECTFREQ '=' timespec ';'
1656 {
1657 if (conf_parser_ctx.pass == 1)
1658 ConFreq(yy_class) = $3;
1659 };
1660
1661 class_max_number: MAX_NUMBER '=' NUMBER ';'
1662 {
1663 if (conf_parser_ctx.pass == 1)
1664 MaxTotal(yy_class) = $3;
1665 };
1666
1667 class_max_global: MAX_GLOBAL '=' NUMBER ';'
1668 {
1669 if (conf_parser_ctx.pass == 1)
1670 MaxGlobal(yy_class) = $3;
1671 };
1672
1673 class_max_local: MAX_LOCAL '=' NUMBER ';'
1674 {
1675 if (conf_parser_ctx.pass == 1)
1676 MaxLocal(yy_class) = $3;
1677 };
1678
1679 class_max_ident: MAX_IDENT '=' NUMBER ';'
1680 {
1681 if (conf_parser_ctx.pass == 1)
1682 MaxIdent(yy_class) = $3;
1683 };
1684
1685 class_sendq: SENDQ '=' sizespec ';'
1686 {
1687 if (conf_parser_ctx.pass == 1)
1688 MaxSendq(yy_class) = $3;
1689 };
1690
1691 class_cidr_bitlen_ipv4: CIDR_BITLEN_IPV4 '=' NUMBER ';'
1692 {
1693 if (conf_parser_ctx.pass == 1)
1694 CidrBitlenIPV4(yy_class) = $3;
1695 };
1696
1697 class_cidr_bitlen_ipv6: CIDR_BITLEN_IPV6 '=' NUMBER ';'
1698 {
1699 if (conf_parser_ctx.pass == 1)
1700 CidrBitlenIPV6(yy_class) = $3;
1701 };
1702
1703 class_number_per_cidr: NUMBER_PER_CIDR '=' NUMBER ';'
1704 {
1705 if (conf_parser_ctx.pass == 1)
1706 NumberPerCidr(yy_class) = $3;
1707 };
1708
1709 /***************************************************************************
1710 * section listen
1711 ***************************************************************************/
1712 listen_entry: LISTEN
1713 {
1714 if (conf_parser_ctx.pass == 2)
1715 {
1716 listener_address = NULL;
1717 listener_flags = 0;
1718 }
1719 } '{' listen_items '}' ';'
1720 {
1721 if (conf_parser_ctx.pass == 2)
1722 {
1723 MyFree(listener_address);
1724 listener_address = NULL;
1725 }
1726 };
1727
1728 listen_flags: IRCD_FLAGS
1729 {
1730 listener_flags = 0;
1731 } '=' listen_flags_items ';';
1732
1733 listen_flags_items: listen_flags_items ',' listen_flags_item | listen_flags_item;
1734 listen_flags_item: T_SSL
1735 {
1736 if (conf_parser_ctx.pass == 2)
1737 listener_flags |= LISTENER_SSL;
1738 } | HIDDEN
1739 {
1740 if (conf_parser_ctx.pass == 2)
1741 listener_flags |= LISTENER_HIDDEN;
1742 } | T_SERVER
1743 {
1744 if (conf_parser_ctx.pass == 2)
1745 listener_flags |= LISTENER_SERVER;
1746 };
1747
1748
1749
1750 listen_items: listen_items listen_item | listen_item;
1751 listen_item: listen_port | listen_flags | listen_address | listen_host | error ';';
1752
1753 listen_port: PORT '=' port_items { listener_flags = 0; } ';';
1754
1755 port_items: port_items ',' port_item | port_item;
1756
1757 port_item: NUMBER
1758 {
1759 if (conf_parser_ctx.pass == 2)
1760 {
1761 if ((listener_flags & LISTENER_SSL))
1762 #ifdef HAVE_LIBCRYPTO
1763 if (!ServerInfo.server_ctx)
1764 #endif
1765 {
1766 yyerror("SSL not available - port closed");
1767 break;
1768 }
1769 add_listener($1, listener_address, listener_flags);
1770 }
1771 } | NUMBER TWODOTS NUMBER
1772 {
1773 if (conf_parser_ctx.pass == 2)
1774 {
1775 int i;
1776
1777 if ((listener_flags & LISTENER_SSL))
1778 #ifdef HAVE_LIBCRYPTO
1779 if (!ServerInfo.server_ctx)
1780 #endif
1781 {
1782 yyerror("SSL not available - port closed");
1783 break;
1784 }
1785
1786 for (i = $1; i <= $3; ++i)
1787 add_listener(i, listener_address, listener_flags);
1788 }
1789 };
1790
1791 listen_address: IP '=' QSTRING ';'
1792 {
1793 if (conf_parser_ctx.pass == 2)
1794 {
1795 MyFree(listener_address);
1796 DupString(listener_address, yylval.string);
1797 }
1798 };
1799
1800 listen_host: HOST '=' QSTRING ';'
1801 {
1802 if (conf_parser_ctx.pass == 2)
1803 {
1804 MyFree(listener_address);
1805 DupString(listener_address, yylval.string);
1806 }
1807 };
1808
1809 /***************************************************************************
1810 * section auth
1811 ***************************************************************************/
1812 auth_entry: IRCD_AUTH
1813 {
1814 if (conf_parser_ctx.pass == 2)
1815 {
1816 yy_conf = make_conf_item(CLIENT_TYPE);
1817 yy_aconf = map_to_conf(yy_conf);
1818 }
1819 else
1820 {
1821 MyFree(class_name);
1822 class_name = NULL;
1823 }
1824 } '{' auth_items '}' ';'
1825 {
1826 if (conf_parser_ctx.pass == 2)
1827 {
1828 struct CollectItem *yy_tmp = NULL;
1829 dlink_node *ptr = NULL, *next_ptr = NULL;
1830
1831 if (yy_aconf->user && yy_aconf->host)
1832 {
1833 conf_add_class_to_conf(yy_conf, class_name);
1834 add_conf_by_address(CONF_CLIENT, yy_aconf);
1835 }
1836 else
1837 delete_conf_item(yy_conf);
1838
1839 /* copy over settings from first struct */
1840 DLINK_FOREACH_SAFE(ptr, next_ptr, col_conf_list.head)
1841 {
1842 struct AccessItem *new_aconf;
1843 struct ConfItem *new_conf;
1844
1845 new_conf = make_conf_item(CLIENT_TYPE);
1846 new_aconf = map_to_conf(new_conf);
1847
1848 yy_tmp = ptr->data;
1849
1850 assert(yy_tmp->user && yy_tmp->host);
1851
1852 if (yy_aconf->passwd != NULL)
1853 DupString(new_aconf->passwd, yy_aconf->passwd);
1854 if (yy_conf->name != NULL)
1855 DupString(new_conf->name, yy_conf->name);
1856 if (yy_aconf->passwd != NULL)
1857 DupString(new_aconf->passwd, yy_aconf->passwd);
1858
1859 new_aconf->flags = yy_aconf->flags;
1860 new_aconf->port = yy_aconf->port;
1861
1862 DupString(new_aconf->user, yy_tmp->user);
1863 collapse(new_aconf->user);
1864
1865 DupString(new_aconf->host, yy_tmp->host);
1866 collapse(new_aconf->host);
1867
1868 conf_add_class_to_conf(new_conf, class_name);
1869 add_conf_by_address(CONF_CLIENT, new_aconf);
1870 dlinkDelete(&yy_tmp->node, &col_conf_list);
1871 free_collect_item(yy_tmp);
1872 }
1873
1874 MyFree(class_name);
1875 class_name = NULL;
1876 yy_conf = NULL;
1877 yy_aconf = NULL;
1878 }
1879 };
1880
1881 auth_items: auth_items auth_item | auth_item;
1882 auth_item: auth_user | auth_passwd | auth_class | auth_flags |
1883 auth_kline_exempt | auth_need_ident |
1884 auth_exceed_limit | auth_no_tilde | auth_gline_exempt |
1885 auth_spoof | auth_spoof_notice |
1886 auth_redir_serv | auth_redir_port | auth_can_flood |
1887 auth_need_password | auth_encrypted | error ';' ;
1888
1889 auth_user: USER '=' QSTRING ';'
1890 {
1891 if (conf_parser_ctx.pass == 2)
1892 {
1893 struct CollectItem *yy_tmp = NULL;
1894 struct split_nuh_item nuh;
1895
1896 nuh.nuhmask = yylval.string;
1897 nuh.nickptr = NULL;
1898 nuh.userptr = userbuf;
1899 nuh.hostptr = hostbuf;
1900
1901 nuh.nicksize = 0;
1902 nuh.usersize = sizeof(userbuf);
1903 nuh.hostsize = sizeof(hostbuf);
1904
1905 split_nuh(&nuh);
1906
1907 if (yy_aconf->user == NULL)
1908 {
1909 DupString(yy_aconf->user, userbuf);
1910 DupString(yy_aconf->host, hostbuf);
1911 }
1912 else
1913 {
1914 yy_tmp = MyMalloc(sizeof(struct CollectItem));
1915
1916 DupString(yy_tmp->user, userbuf);
1917 DupString(yy_tmp->host, hostbuf);
1918
1919 dlinkAdd(yy_tmp, &yy_tmp->node, &col_conf_list);
1920 }
1921 }
1922 };
1923
1924 /* XXX - IP/IPV6 tags don't exist anymore - put IP/IPV6 into user. */
1925
1926 auth_passwd: PASSWORD '=' QSTRING ';'
1927 {
1928 if (conf_parser_ctx.pass == 2)
1929 {
1930 /* be paranoid */
1931 if (yy_aconf->passwd != NULL)
1932 memset(yy_aconf->passwd, 0, strlen(yy_aconf->passwd));
1933
1934 MyFree(yy_aconf->passwd);
1935 DupString(yy_aconf->passwd, yylval.string);
1936 }
1937 };
1938
1939 auth_spoof_notice: SPOOF_NOTICE '=' TBOOL ';'
1940 {
1941 if (conf_parser_ctx.pass == 2)
1942 {
1943 if (yylval.number)
1944 yy_aconf->flags |= CONF_FLAGS_SPOOF_NOTICE;
1945 else
1946 yy_aconf->flags &= ~CONF_FLAGS_SPOOF_NOTICE;
1947 }
1948 };
1949
1950 auth_class: CLASS '=' QSTRING ';'
1951 {
1952 if (conf_parser_ctx.pass == 2)
1953 {
1954 MyFree(class_name);
1955 DupString(class_name, yylval.string);
1956 }
1957 };
1958
1959 auth_encrypted: ENCRYPTED '=' TBOOL ';'
1960 {
1961 if (conf_parser_ctx.pass == 2)
1962 {
1963 if (yylval.number)
1964 SetConfEncrypted(yy_aconf);
1965 else
1966 ClearConfEncrypted(yy_aconf);
1967 }
1968 };
1969
1970 auth_flags: IRCD_FLAGS
1971 {
1972 } '=' auth_flags_items ';';
1973
1974 auth_flags_items: auth_flags_items ',' auth_flags_item | auth_flags_item;
1975 auth_flags_item: NOT { not_atom = 1; } auth_flags_item_atom
1976 | { not_atom = 0; } auth_flags_item_atom;
1977
1978 auth_flags_item_atom: SPOOF_NOTICE
1979 {
1980 if (conf_parser_ctx.pass == 2)
1981 {
1982 if (not_atom) yy_aconf->flags &= ~CONF_FLAGS_SPOOF_NOTICE;
1983 else yy_aconf->flags |= CONF_FLAGS_SPOOF_NOTICE;
1984 }
1985
1986 } | EXCEED_LIMIT
1987 {
1988 if (conf_parser_ctx.pass == 2)
1989 {
1990 if (not_atom) yy_aconf->flags &= ~CONF_FLAGS_NOLIMIT;
1991 else yy_aconf->flags |= CONF_FLAGS_NOLIMIT;
1992 }
1993 } | KLINE_EXEMPT
1994 {
1995 if (conf_parser_ctx.pass == 2)
1996 {
1997 if (not_atom) yy_aconf->flags &= ~CONF_FLAGS_EXEMPTKLINE;
1998 else yy_aconf->flags |= CONF_FLAGS_EXEMPTKLINE;
1999 }
2000 } | NEED_IDENT
2001 {
2002 if (conf_parser_ctx.pass == 2)
2003 {
2004 if (not_atom) yy_aconf->flags &= ~CONF_FLAGS_NEED_IDENTD;
2005 else yy_aconf->flags |= CONF_FLAGS_NEED_IDENTD;
2006 }
2007 } | CAN_FLOOD
2008 {
2009 if (conf_parser_ctx.pass == 2)
2010 {
2011 if (not_atom) yy_aconf->flags &= ~CONF_FLAGS_CAN_FLOOD;
2012 else yy_aconf->flags |= CONF_FLAGS_CAN_FLOOD;
2013 }
2014 } | CAN_IDLE
2015 {
2016 if (conf_parser_ctx.pass == 2)
2017 {
2018 if (not_atom) yy_aconf->flags &= ~CONF_FLAGS_IDLE_LINED;
2019 else yy_aconf->flags |= CONF_FLAGS_IDLE_LINED;
2020 }
2021 } | NO_TILDE
2022 {
2023 if (conf_parser_ctx.pass == 2)
2024 {
2025 if (not_atom) yy_aconf->flags &= ~CONF_FLAGS_NO_TILDE;
2026 else yy_aconf->flags |= CONF_FLAGS_NO_TILDE;
2027 }
2028 } | GLINE_EXEMPT
2029 {
2030 if (conf_parser_ctx.pass == 2)
2031 {
2032 if (not_atom) yy_aconf->flags &= ~CONF_FLAGS_EXEMPTGLINE;
2033 else yy_aconf->flags |= CONF_FLAGS_EXEMPTGLINE;
2034 }
2035 } | RESV_EXEMPT
2036 {
2037 if (conf_parser_ctx.pass == 2)
2038 {
2039 if (not_atom) yy_aconf->flags &= ~CONF_FLAGS_EXEMPTRESV;
2040 else yy_aconf->flags |= CONF_FLAGS_EXEMPTRESV;
2041 }
2042 } | NEED_PASSWORD
2043 {
2044 if (conf_parser_ctx.pass == 2)
2045 {
2046 if (not_atom) yy_aconf->flags &= ~CONF_FLAGS_NEED_PASSWORD;
2047 else yy_aconf->flags |= CONF_FLAGS_NEED_PASSWORD;
2048 }
2049 };
2050
2051 auth_kline_exempt: KLINE_EXEMPT '=' TBOOL ';'
2052 {
2053 if (conf_parser_ctx.pass == 2)
2054 {
2055 if (yylval.number)
2056 yy_aconf->flags |= CONF_FLAGS_EXEMPTKLINE;
2057 else
2058 yy_aconf->flags &= ~CONF_FLAGS_EXEMPTKLINE;
2059 }
2060 };
2061
2062 auth_need_ident: NEED_IDENT '=' TBOOL ';'
2063 {
2064 if (conf_parser_ctx.pass == 2)
2065 {
2066 if (yylval.number)
2067 yy_aconf->flags |= CONF_FLAGS_NEED_IDENTD;
2068 else
2069 yy_aconf->flags &= ~CONF_FLAGS_NEED_IDENTD;
2070 }
2071 };
2072
2073 auth_exceed_limit: EXCEED_LIMIT '=' TBOOL ';'
2074 {
2075 if (conf_parser_ctx.pass == 2)
2076 {
2077 if (yylval.number)
2078 yy_aconf->flags |= CONF_FLAGS_NOLIMIT;
2079 else
2080 yy_aconf->flags &= ~CONF_FLAGS_NOLIMIT;
2081 }
2082 };
2083
2084 auth_can_flood: CAN_FLOOD '=' TBOOL ';'
2085 {
2086 if (conf_parser_ctx.pass == 2)
2087 {
2088 if (yylval.number)
2089 yy_aconf->flags |= CONF_FLAGS_CAN_FLOOD;
2090 else
2091 yy_aconf->flags &= ~CONF_FLAGS_CAN_FLOOD;
2092 }
2093 };
2094
2095 auth_no_tilde: NO_TILDE '=' TBOOL ';'
2096 {
2097 if (conf_parser_ctx.pass == 2)
2098 {
2099 if (yylval.number)
2100 yy_aconf->flags |= CONF_FLAGS_NO_TILDE;
2101 else
2102 yy_aconf->flags &= ~CONF_FLAGS_NO_TILDE;
2103 }
2104 };
2105
2106 auth_gline_exempt: GLINE_EXEMPT '=' TBOOL ';'
2107 {
2108 if (conf_parser_ctx.pass == 2)
2109 {
2110 if (yylval.number)
2111 yy_aconf->flags |= CONF_FLAGS_EXEMPTGLINE;
2112 else
2113 yy_aconf->flags &= ~CONF_FLAGS_EXEMPTGLINE;
2114 }
2115 };
2116
2117 /* XXX - need check for illegal hostnames here */
2118 auth_spoof: SPOOF '=' QSTRING ';'
2119 {
2120 if (conf_parser_ctx.pass == 2)
2121 {
2122 MyFree(yy_conf->name);
2123
2124 if (strlen(yylval.string) < HOSTLEN)
2125 {
2126 DupString(yy_conf->name, yylval.string);
2127 yy_aconf->flags |= CONF_FLAGS_SPOOF_IP;
2128 }
2129 else
2130 {
2131 ilog(L_ERROR, "Spoofs must be less than %d..ignoring it", HOSTLEN);
2132 yy_conf->name = NULL;
2133 }
2134 }
2135 };
2136
2137 auth_redir_serv: REDIRSERV '=' QSTRING ';'
2138 {
2139 if (conf_parser_ctx.pass == 2)
2140 {
2141 yy_aconf->flags |= CONF_FLAGS_REDIR;
2142 MyFree(yy_conf->name);
2143 DupString(yy_conf->name, yylval.string);
2144 }
2145 };
2146
2147 auth_redir_port: REDIRPORT '=' NUMBER ';'
2148 {
2149 if (conf_parser_ctx.pass == 2)
2150 {
2151 yy_aconf->flags |= CONF_FLAGS_REDIR;
2152 yy_aconf->port = $3;
2153 }
2154 };
2155
2156 auth_need_password: NEED_PASSWORD '=' TBOOL ';'
2157 {
2158 if (conf_parser_ctx.pass == 2)
2159 {
2160 if (yylval.number)
2161 yy_aconf->flags |= CONF_FLAGS_NEED_PASSWORD;
2162 else
2163 yy_aconf->flags &= ~CONF_FLAGS_NEED_PASSWORD;
2164 }
2165 };
2166
2167
2168 /***************************************************************************
2169 * section resv
2170 ***************************************************************************/
2171 resv_entry: RESV
2172 {
2173 if (conf_parser_ctx.pass == 2)
2174 {
2175 MyFree(resv_reason);
2176 resv_reason = NULL;
2177 }
2178 } '{' resv_items '}' ';'
2179 {
2180 if (conf_parser_ctx.pass == 2)
2181 {
2182 MyFree(resv_reason);
2183 resv_reason = NULL;
2184 }
2185 };
2186
2187 resv_items: resv_items resv_item | resv_item;
2188 resv_item: resv_creason | resv_channel | resv_nick | error ';' ;
2189
2190 resv_creason: REASON '=' QSTRING ';'
2191 {
2192 if (conf_parser_ctx.pass == 2)
2193 {
2194 MyFree(resv_reason);
2195 DupString(resv_reason, yylval.string);
2196 }
2197 };
2198
2199 resv_channel: CHANNEL '=' QSTRING ';'
2200 {
2201 if (conf_parser_ctx.pass == 2)
2202 {
2203 if (IsChanPrefix(*yylval.string))
2204 {
2205 char def_reason[] = "No reason";
2206
2207 create_channel_resv(yylval.string, resv_reason != NULL ? resv_reason : def_reason, 1);
2208 }
2209 }
2210 /* ignore it for now.. but we really should make a warning if
2211 * its an erroneous name --fl_ */
2212 };
2213
2214 resv_nick: NICK '=' QSTRING ';'
2215 {
2216 if (conf_parser_ctx.pass == 2)
2217 {
2218 char def_reason[] = "No reason";
2219
2220 create_nick_resv(yylval.string, resv_reason != NULL ? resv_reason : def_reason, 1);
2221 }
2222 };
2223
2224 /***************************************************************************
2225 * section shared, for sharing remote klines etc.
2226 ***************************************************************************/
2227 shared_entry: T_SHARED
2228 {
2229 if (conf_parser_ctx.pass == 2)
2230 {
2231 yy_conf = make_conf_item(ULINE_TYPE);
2232 yy_match_item = map_to_conf(yy_conf);
2233 yy_match_item->action = SHARED_ALL;
2234 }
2235 } '{' shared_items '}' ';'
2236 {
2237 if (conf_parser_ctx.pass == 2)
2238 {
2239 yy_conf = NULL;
2240 }
2241 };
2242
2243 shared_items: shared_items shared_item | shared_item;
2244 shared_item: shared_name | shared_user | shared_type | error ';' ;
2245
2246 shared_name: NAME '=' QSTRING ';'
2247 {
2248 if (conf_parser_ctx.pass == 2)
2249 {
2250 MyFree(yy_conf->name);
2251 DupString(yy_conf->name, yylval.string);
2252 }
2253 };
2254
2255 shared_user: USER '=' QSTRING ';'
2256 {
2257 if (conf_parser_ctx.pass == 2)
2258 {
2259 struct split_nuh_item nuh;
2260
2261 nuh.nuhmask = yylval.string;
2262 nuh.nickptr = NULL;
2263 nuh.userptr = userbuf;
2264 nuh.hostptr = hostbuf;
2265
2266 nuh.nicksize = 0;
2267 nuh.usersize = sizeof(userbuf);
2268 nuh.hostsize = sizeof(hostbuf);
2269
2270 split_nuh(&nuh);
2271
2272 DupString(yy_match_item->user, userbuf);
2273 DupString(yy_match_item->host, hostbuf);
2274 }
2275 };
2276
2277 shared_type: TYPE
2278 {
2279 if (conf_parser_ctx.pass == 2)
2280 yy_match_item->action = 0;
2281 } '=' shared_types ';' ;
2282
2283 shared_types: shared_types ',' shared_type_item | shared_type_item;
2284 shared_type_item: KLINE
2285 {
2286 if (conf_parser_ctx.pass == 2)
2287 yy_match_item->action |= SHARED_KLINE;
2288 } | TKLINE
2289 {
2290 if (conf_parser_ctx.pass == 2)
2291 yy_match_item->action |= SHARED_TKLINE;
2292 } | UNKLINE
2293 {
2294 if (conf_parser_ctx.pass == 2)
2295 yy_match_item->action |= SHARED_UNKLINE;
2296 } | XLINE
2297 {
2298 if (conf_parser_ctx.pass == 2)
2299 yy_match_item->action |= SHARED_XLINE;
2300 } | TXLINE
2301 {
2302 if (conf_parser_ctx.pass == 2)
2303 yy_match_item->action |= SHARED_TXLINE;
2304 } | T_UNXLINE
2305 {
2306 if (conf_parser_ctx.pass == 2)
2307 yy_match_item->action |= SHARED_UNXLINE;
2308 } | RESV
2309 {
2310 if (conf_parser_ctx.pass == 2)
2311 yy_match_item->action |= SHARED_RESV;
2312 } | TRESV
2313 {
2314 if (conf_parser_ctx.pass == 2)
2315 yy_match_item->action |= SHARED_TRESV;
2316 } | T_UNRESV
2317 {
2318 if (conf_parser_ctx.pass == 2)
2319 yy_match_item->action |= SHARED_UNRESV;
2320 } | T_LOCOPS
2321 {
2322 if (conf_parser_ctx.pass == 2)
2323 yy_match_item->action |= SHARED_LOCOPS;
2324 } | T_ALL
2325 {
2326 if (conf_parser_ctx.pass == 2)
2327 yy_match_item->action = SHARED_ALL;
2328 };
2329
2330 /***************************************************************************
2331 * section cluster
2332 ***************************************************************************/
2333 cluster_entry: T_CLUSTER
2334 {
2335 if (conf_parser_ctx.pass == 2)
2336 {
2337 yy_conf = make_conf_item(CLUSTER_TYPE);
2338 yy_conf->flags = SHARED_ALL;
2339 }
2340 } '{' cluster_items '}' ';'
2341 {
2342 if (conf_parser_ctx.pass == 2)
2343 {
2344 if (yy_conf->name == NULL)
2345 DupString(yy_conf->name, "*");
2346 yy_conf = NULL;
2347 }
2348 };
2349
2350 cluster_items: cluster_items cluster_item | cluster_item;
2351 cluster_item: cluster_name | cluster_type | error ';' ;
2352
2353 cluster_name: NAME '=' QSTRING ';'
2354 {
2355 if (conf_parser_ctx.pass == 2)
2356 DupString(yy_conf->name, yylval.string);
2357 };
2358
2359 cluster_type: TYPE
2360 {
2361 if (conf_parser_ctx.pass == 2)
2362 yy_conf->flags = 0;
2363 } '=' cluster_types ';' ;
2364
2365 cluster_types: cluster_types ',' cluster_type_item | cluster_type_item;
2366 cluster_type_item: KLINE
2367 {
2368 if (conf_parser_ctx.pass == 2)
2369 yy_conf->flags |= SHARED_KLINE;
2370 } | TKLINE
2371 {
2372 if (conf_parser_ctx.pass == 2)
2373 yy_conf->flags |= SHARED_TKLINE;
2374 } | UNKLINE
2375 {
2376 if (conf_parser_ctx.pass == 2)
2377 yy_conf->flags |= SHARED_UNKLINE;
2378 } | XLINE
2379 {
2380 if (conf_parser_ctx.pass == 2)
2381 yy_conf->flags |= SHARED_XLINE;
2382 } | TXLINE
2383 {
2384 if (conf_parser_ctx.pass == 2)
2385 yy_conf->flags |= SHARED_TXLINE;
2386 } | T_UNXLINE
2387 {
2388 if (conf_parser_ctx.pass == 2)
2389 yy_conf->flags |= SHARED_UNXLINE;
2390 } | RESV
2391 {
2392 if (conf_parser_ctx.pass == 2)
2393 yy_conf->flags |= SHARED_RESV;
2394 } | TRESV
2395 {
2396 if (conf_parser_ctx.pass == 2)
2397 yy_conf->flags |= SHARED_TRESV;
2398 } | T_UNRESV
2399 {
2400 if (conf_parser_ctx.pass == 2)
2401 yy_conf->flags |= SHARED_UNRESV;
2402 } | T_LOCOPS
2403 {
2404 if (conf_parser_ctx.pass == 2)
2405 yy_conf->flags |= SHARED_LOCOPS;
2406 } | T_ALL
2407 {
2408 if (conf_parser_ctx.pass == 2)
2409 yy_conf->flags = SHARED_ALL;
2410 };
2411
2412 /***************************************************************************
2413 * section connect
2414 ***************************************************************************/
2415 connect_entry: CONNECT
2416 {
2417 if (conf_parser_ctx.pass == 2)
2418 {
2419 yy_conf = make_conf_item(SERVER_TYPE);
2420 yy_aconf = (struct AccessItem *)map_to_conf(yy_conf);
2421 yy_aconf->passwd = NULL;
2422 /* defaults */
2423 yy_aconf->port = PORTNUM;
2424
2425 if (ConfigFileEntry.burst_away)
2426 yy_aconf->flags = CONF_FLAGS_BURST_AWAY;
2427 }
2428 else
2429 {
2430 MyFree(class_name);
2431 class_name = NULL;
2432 }
2433 } connect_name_b '{' connect_items '}' ';'
2434 {
2435 if (conf_parser_ctx.pass == 2)
2436 {
2437 struct CollectItem *yy_hconf=NULL;
2438 struct CollectItem *yy_lconf=NULL;
2439 dlink_node *ptr;
2440 dlink_node *next_ptr;
2441 #ifdef HAVE_LIBCRYPTO
2442 if (yy_aconf->host &&
2443 ((yy_aconf->passwd && yy_aconf->spasswd) ||
2444 (yy_aconf->rsa_public_key && IsConfCryptLink(yy_aconf))))
2445 #else /* !HAVE_LIBCRYPTO */
2446 if (yy_aconf->host && !IsConfCryptLink(yy_aconf) &&
2447 yy_aconf->passwd && yy_aconf->spasswd)
2448 #endif /* !HAVE_LIBCRYPTO */
2449 {
2450 if (conf_add_server(yy_conf, class_name) == -1)
2451 {
2452 delete_conf_item(yy_conf);
2453 yy_conf = NULL;
2454 yy_aconf = NULL;
2455 }
2456 }
2457 else
2458 {
2459 /* Even if yy_conf ->name is NULL
2460 * should still unhook any hub/leaf confs still pending
2461 */
2462 unhook_hub_leaf_confs();
2463
2464 if (yy_conf->name != NULL)
2465 {
2466 #ifndef HAVE_LIBCRYPTO
2467 if (IsConfCryptLink(yy_aconf))
2468 yyerror("Ignoring connect block -- no OpenSSL support");
2469 #else
2470 if (IsConfCryptLink(yy_aconf) && !yy_aconf->rsa_public_key)
2471 yyerror("Ignoring connect block -- missing key");
2472 #endif
2473 if (yy_aconf->host == NULL)
2474 yyerror("Ignoring connect block -- missing host");
2475 else if (!IsConfCryptLink(yy_aconf) &&
2476 (!yy_aconf->passwd || !yy_aconf->spasswd))
2477 yyerror("Ignoring connect block -- missing password");
2478 }
2479
2480
2481 /* XXX
2482 * This fixes a try_connections() core (caused by invalid class_ptr
2483 * pointers) reported by metalrock. That's an ugly fix, but there
2484 * is currently no better way. The entire config subsystem needs an
2485 * rewrite ASAP. make_conf_item() shouldn't really add things onto
2486 * a doubly linked list immediately without any sanity checks! -Michael
2487 */
2488 delete_conf_item(yy_conf);
2489
2490 yy_aconf = NULL;
2491 yy_conf = NULL;
2492 }
2493
2494 /*
2495 * yy_conf is still pointing at the server that is having
2496 * a connect block built for it. This means, y_aconf->name
2497 * points to the actual irc name this server will be known as.
2498 * Now this new server has a set or even just one hub_mask (or leaf_mask)
2499 * given in the link list at yy_hconf. Fill in the HUB confs
2500 * from this link list now.
2501 */
2502 DLINK_FOREACH_SAFE(ptr, next_ptr, hub_conf_list.head)
2503 {
2504 struct ConfItem *new_hub_conf;
2505 struct MatchItem *match_item;
2506
2507 yy_hconf = ptr->data;
2508
2509 /* yy_conf == NULL is a fatal error for this connect block! */
2510 if ((yy_conf != NULL) && (yy_conf->name != NULL))
2511 {
2512 new_hub_conf = make_conf_item(HUB_TYPE);
2513 match_item = (struct MatchItem *)map_to_conf(new_hub_conf);
2514 DupString(new_hub_conf->name, yy_conf->name);
2515 if (yy_hconf->user != NULL)
2516 DupString(match_item->user, yy_hconf->user);
2517 else
2518 DupString(match_item->user, "*");
2519 if (yy_hconf->host != NULL)
2520 DupString(match_item->host, yy_hconf->host);
2521 else
2522 DupString(match_item->host, "*");
2523 }
2524 dlinkDelete(&yy_hconf->node, &hub_conf_list);
2525 free_collect_item(yy_hconf);
2526 }
2527
2528 /* Ditto for the LEAF confs */
2529
2530 DLINK_FOREACH_SAFE(ptr, next_ptr, leaf_conf_list.head)
2531 {
2532 struct ConfItem *new_leaf_conf;
2533 struct MatchItem *match_item;
2534
2535 yy_lconf = ptr->data;
2536
2537 if ((yy_conf != NULL) && (yy_conf->name != NULL))
2538 {
2539 new_leaf_conf = make_conf_item(LEAF_TYPE);
2540 match_item = (struct MatchItem *)map_to_conf(new_leaf_conf);
2541 DupString(new_leaf_conf->name, yy_conf->name);
2542 if (yy_lconf->user != NULL)
2543 DupString(match_item->user, yy_lconf->user);
2544 else
2545 DupString(match_item->user, "*");
2546 if (yy_lconf->host != NULL)
2547 DupString(match_item->host, yy_lconf->host);
2548 else
2549 DupString(match_item->host, "*");
2550 }
2551 dlinkDelete(&yy_lconf->node, &leaf_conf_list);
2552 free_collect_item(yy_lconf);
2553 }
2554 MyFree(class_name);
2555 class_name = NULL;
2556 yy_conf = NULL;
2557 yy_aconf = NULL;
2558 }
2559 };
2560
2561 connect_name_b: | connect_name_t;
2562 connect_items: connect_items connect_item | connect_item;
2563 connect_item: connect_name | connect_host | connect_vhost |
2564 connect_send_password | connect_accept_password |
2565 connect_aftype | connect_port |
2566 connect_fakename | connect_flags | connect_hub_mask |
2567 connect_leaf_mask | connect_class | connect_auto |
2568 connect_encrypted | connect_compressed | connect_cryptlink |
2569 connect_rsa_public_key_file | connect_cipher_preference |
2570 connect_topicburst | error ';' ;
2571
2572 connect_name: NAME '=' QSTRING ';'
2573 {
2574 if (conf_parser_ctx.pass == 2)
2575 {
2576 if (yy_conf->name != NULL)
2577 yyerror("Multiple connect name entry");
2578
2579 MyFree(yy_conf->name);
2580 DupString(yy_conf->name, yylval.string);
2581 }
2582 };
2583
2584 connect_name_t: QSTRING
2585 {
2586 if (conf_parser_ctx.pass == 2)
2587 {
2588 if (yy_conf->name != NULL)
2589 yyerror("Multiple connect name entry");
2590
2591 MyFree(yy_conf->name);
2592 DupString(yy_conf->name, yylval.string);
2593 }
2594 };
2595
2596 connect_host: HOST '=' QSTRING ';'
2597 {
2598 if (conf_parser_ctx.pass == 2)
2599 {
2600 MyFree(yy_aconf->host);
2601 DupString(yy_aconf->host, yylval.string);
2602 }
2603 };
2604
2605 connect_vhost: VHOST '=' QSTRING ';'
2606 {
2607 if (conf_parser_ctx.pass == 2)
2608 {
2609 struct addrinfo hints, *res;
2610
2611 memset(&hints, 0, sizeof(hints));
2612
2613 hints.ai_family = AF_UNSPEC;
2614 hints.ai_socktype = SOCK_STREAM;
2615 hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST;
2616
2617 if (irc_getaddrinfo(yylval.string, NULL, &hints, &res))
2618 ilog(L_ERROR, "Invalid netmask for server vhost(%s)", yylval.string);
2619 else
2620 {
2621 assert(res != NULL);
2622
2623 memcpy(&yy_aconf->my_ipnum, res->ai_addr, res->ai_addrlen);
2624 yy_aconf->my_ipnum.ss.ss_family = res->ai_family;
2625 yy_aconf->my_ipnum.ss_len = res->ai_addrlen;
2626 irc_freeaddrinfo(res);
2627 }
2628 }
2629 };
2630
2631 connect_send_password: SEND_PASSWORD '=' QSTRING ';'
2632 {
2633 if (conf_parser_ctx.pass == 2)
2634 {
2635 if ($3[0] == ':')
2636 yyerror("Server passwords cannot begin with a colon");
2637 else if (strchr($3, ' ') != NULL)
2638 yyerror("Server passwords cannot contain spaces");
2639 else {
2640 if (yy_aconf->spasswd != NULL)
2641 memset(yy_aconf->spasswd, 0, strlen(yy_aconf->spasswd));
2642
2643 MyFree(yy_aconf->spasswd);
2644 DupString(yy_aconf->spasswd, yylval.string);
2645 }
2646 }
2647 };
2648
2649 connect_accept_password: ACCEPT_PASSWORD '=' QSTRING ';'
2650 {
2651 if (conf_parser_ctx.pass == 2)
2652 {
2653 if ($3[0] == ':')
2654 yyerror("Server passwords cannot begin with a colon");
2655 else if (strchr($3, ' ') != NULL)
2656 yyerror("Server passwords cannot contain spaces");
2657 else {
2658 if (yy_aconf->passwd != NULL)
2659 memset(yy_aconf->passwd, 0, strlen(yy_aconf->passwd));
2660
2661 MyFree(yy_aconf->passwd);
2662 DupString(yy_aconf->passwd, yylval.string);
2663 }
2664 }
2665 };
2666
2667 connect_port: PORT '=' NUMBER ';'
2668 {
2669 if (conf_parser_ctx.pass == 2)
2670 yy_aconf->port = $3;
2671 };
2672
2673 connect_aftype: AFTYPE '=' T_IPV4 ';'
2674 {
2675 if (conf_parser_ctx.pass == 2)
2676 yy_aconf->aftype = AF_INET;
2677 } | AFTYPE '=' T_IPV6 ';'
2678 {
2679 #ifdef IPV6
2680 if (conf_parser_ctx.pass == 2)
2681 yy_aconf->aftype = AF_INET6;
2682 #endif
2683 };
2684
2685 connect_fakename: FAKENAME '=' QSTRING ';'
2686 {
2687 if (conf_parser_ctx.pass == 2)
2688 {
2689 MyFree(yy_aconf->fakename);
2690 DupString(yy_aconf->fakename, yylval.string);
2691 }
2692 };
2693
2694 connect_flags: IRCD_FLAGS
2695 {
2696 } '=' connect_flags_items ';';
2697
2698 connect_flags_items: connect_flags_items ',' connect_flags_item | connect_flags_item;
2699 connect_flags_item: NOT { not_atom = 1; } connect_flags_item_atom
2700 | { not_atom = 0; } connect_flags_item_atom;
2701
2702 connect_flags_item_atom: COMPRESSED
2703 {
2704 if (conf_parser_ctx.pass == 2)
2705 #ifndef HAVE_LIBZ
2706 yyerror("Ignoring flags = compressed; -- no zlib support");
2707 #else
2708 {
2709 if (not_atom)ClearConfCompressed(yy_aconf);
2710 else SetConfCompressed(yy_aconf);
2711 }
2712 #endif
2713 } | CRYPTLINK
2714 {
2715 if (conf_parser_ctx.pass == 2)
2716 {
2717 if (not_atom)ClearConfCryptLink(yy_aconf);
2718 else SetConfCryptLink(yy_aconf);
2719 }
2720 } | AUTOCONN
2721 {
2722 if (conf_parser_ctx.pass == 2)
2723 {
2724 if (not_atom)ClearConfAllowAutoConn(yy_aconf);
2725 else SetConfAllowAutoConn(yy_aconf);
2726 }
2727 } | BURST_AWAY
2728 {
2729 if (conf_parser_ctx.pass == 2)
2730 {
2731 if (not_atom)ClearConfAwayBurst(yy_aconf);
2732 else SetConfAwayBurst(yy_aconf);
2733 }
2734 } | TOPICBURST
2735 {
2736 if (conf_parser_ctx.pass == 2)
2737 {
2738 if (not_atom)ClearConfTopicBurst(yy_aconf);
2739 else SetConfTopicBurst(yy_aconf);
2740 }
2741 }
2742 ;
2743
2744 connect_rsa_public_key_file: RSA_PUBLIC_KEY_FILE '=' QSTRING ';'
2745 {
2746 #ifdef HAVE_LIBCRYPTO
2747 if (conf_parser_ctx.pass == 2)
2748 {
2749 BIO *file;
2750
2751 if (yy_aconf->rsa_public_key != NULL)
2752 {
2753 RSA_free(yy_aconf->rsa_public_key);
2754 yy_aconf->rsa_public_key = NULL;
2755 }
2756
2757 if (yy_aconf->rsa_public_key_file != NULL)
2758 {
2759 MyFree(yy_aconf->rsa_public_key_file);
2760 yy_aconf->rsa_public_key_file = NULL;
2761 }
2762
2763 DupString(yy_aconf->rsa_public_key_file, yylval.string);
2764
2765 if ((file = BIO_new_file(yylval.string, "r")) == NULL)
2766 {
2767 yyerror("Ignoring rsa_public_key_file -- file doesn't exist");
2768 break;
2769 }
2770
2771 yy_aconf->rsa_public_key = (RSA *)PEM_read_bio_RSA_PUBKEY(file, NULL, 0, NULL);
2772
2773 if (yy_aconf->rsa_public_key == NULL)
2774 {
2775 yyerror("Ignoring rsa_public_key_file -- Key invalid; check key syntax.");
2776 break;
2777 }
2778
2779 BIO_set_close(file, BIO_CLOSE);
2780 BIO_free(file);
2781 }
2782 #endif /* HAVE_LIBCRYPTO */
2783 };
2784
2785 connect_encrypted: ENCRYPTED '=' TBOOL ';'
2786 {
2787 if (conf_parser_ctx.pass == 2)
2788 {
2789 if (yylval.number)
2790 yy_aconf->flags |= CONF_FLAGS_ENCRYPTED;
2791 else
2792 yy_aconf->flags &= ~CONF_FLAGS_ENCRYPTED;
2793 }
2794 };
2795
2796 connect_cryptlink: CRYPTLINK '=' TBOOL ';'
2797 {
2798 if (conf_parser_ctx.pass == 2)
2799 {
2800 if (yylval.number)
2801 yy_aconf->flags |= CONF_FLAGS_CRYPTLINK;
2802 else
2803 yy_aconf->flags &= ~CONF_FLAGS_CRYPTLINK;
2804 }
2805 };
2806
2807 connect_compressed: COMPRESSED '=' TBOOL ';'
2808 {
2809 if (conf_parser_ctx.pass == 2)
2810 {
2811 if (yylval.number)
2812 #ifndef HAVE_LIBZ
2813 yyerror("Ignoring compressed=yes; -- no zlib support");
2814 #else
2815 yy_aconf->flags |= CONF_FLAGS_COMPRESSED;
2816 #endif
2817 else
2818 yy_aconf->flags &= ~CONF_FLAGS_COMPRESSED;
2819 }
2820 };
2821
2822 connect_auto: AUTOCONN '=' TBOOL ';'
2823 {
2824 if (conf_parser_ctx.pass == 2)
2825 {
2826 if (yylval.number)
2827 yy_aconf->flags |= CONF_FLAGS_ALLOW_AUTO_CONN;
2828 else
2829 yy_aconf->flags &= ~CONF_FLAGS_ALLOW_AUTO_CONN;
2830 }
2831 };
2832
2833 connect_topicburst: TOPICBURST '=' TBOOL ';'
2834 {
2835 if (conf_parser_ctx.pass == 2)
2836 {
2837 if (yylval.number)
2838 SetConfTopicBurst(yy_aconf);
2839 else
2840 ClearConfTopicBurst(yy_aconf);
2841 }
2842 };
2843
2844 connect_hub_mask: HUB_MASK '=' QSTRING ';'
2845 {
2846 if (conf_parser_ctx.pass == 2)
2847 {
2848 struct CollectItem *yy_tmp;
2849
2850 yy_tmp = (struct CollectItem *)MyMalloc(sizeof(struct CollectItem));
2851 DupString(yy_tmp->host, yylval.string);
2852 DupString(yy_tmp->user, "*");
2853 dlinkAdd(yy_tmp, &yy_tmp->node, &hub_conf_list);
2854 }
2855 };
2856
2857 connect_leaf_mask: LEAF_MASK '=' QSTRING ';'
2858 {
2859 if (conf_parser_ctx.pass == 2)
2860 {
2861 struct CollectItem *yy_tmp;
2862
2863 yy_tmp = (struct CollectItem *)MyMalloc(sizeof(struct CollectItem));
2864 DupString(yy_tmp->host, yylval.string);
2865 DupString(yy_tmp->user, "*");
2866 dlinkAdd(yy_tmp, &yy_tmp->node, &leaf_conf_list);
2867 }
2868 };
2869
2870 connect_class: CLASS '=' QSTRING ';'
2871 {
2872 if (conf_parser_ctx.pass == 2)
2873 {
2874 MyFree(class_name);
2875 DupString(class_name, yylval.string);
2876 }
2877 };
2878
2879 connect_cipher_preference: CIPHER_PREFERENCE '=' QSTRING ';'
2880 {
2881 #ifdef HAVE_LIBCRYPTO
2882 if (conf_parser_ctx.pass == 2)
2883 {
2884 struct EncCapability *ecap;
2885 const char *cipher_name;
2886 int found = 0;
2887
2888 yy_aconf->cipher_preference = NULL;
2889 cipher_name = yylval.string;
2890
2891 for (ecap = CipherTable; ecap->name; ecap++)
2892 {
2893 if ((irccmp(ecap->name, cipher_name) == 0) &&
2894 (ecap->cap & CAP_ENC_MASK))
2895 {
2896 yy_aconf->cipher_preference = ecap;
2897 found = 1;
2898 break;
2899 }
2900 }
2901
2902 if (!found)
2903 yyerror("Invalid cipher");
2904 }
2905 #else
2906 if (conf_parser_ctx.pass == 2)
2907 yyerror("Ignoring cipher_preference -- no OpenSSL support");
2908 #endif
2909 };
2910
2911 /***************************************************************************
2912 * section kill
2913 ***************************************************************************/
2914 kill_entry: KILL
2915 {
2916 if (conf_parser_ctx.pass == 2)
2917 {
2918 userbuf[0] = hostbuf[0] = reasonbuf[0] = '\0';
2919 regex_ban = 0;
2920 }
2921 } '{' kill_items '}' ';'
2922 {
2923 if (conf_parser_ctx.pass == 2)
2924 {
2925 if (userbuf[0] && hostbuf[0])
2926 {
2927 if (regex_ban)
2928 {
2929 pcre *exp_user = NULL;
2930 pcre *exp_host = NULL;
2931 const char *errptr = NULL;
2932
2933 if (!(exp_user = ircd_pcre_compile(userbuf, &errptr)) ||
2934 !(exp_host = ircd_pcre_compile(hostbuf, &errptr)))
2935 {
2936 ilog(L_ERROR, "Failed to add regular expression based K-Line: %s",
2937 errptr);
2938 break;
2939 }
2940
2941 yy_conf = make_conf_item(RKLINE_TYPE);
2942 yy_aconf = map_to_conf(yy_conf);
2943
2944 yy_aconf->regexuser = exp_user;
2945 yy_aconf->regexhost = exp_host;
2946
2947 DupString(yy_aconf->user, userbuf);
2948 DupString(yy_aconf->host, hostbuf);
2949
2950 if (reasonbuf[0])
2951 DupString(yy_aconf->reason, reasonbuf);
2952 else
2953 DupString(yy_aconf->reason, "No reason");
2954 }
2955 else
2956 {
2957 yy_conf = make_conf_item(KLINE_TYPE);
2958 yy_aconf = map_to_conf(yy_conf);
2959
2960 DupString(yy_aconf->user, userbuf);
2961 DupString(yy_aconf->host, hostbuf);
2962
2963 if (reasonbuf[0])
2964 DupString(yy_aconf->reason, reasonbuf);
2965 else
2966 DupString(yy_aconf->reason, "No reason");
2967 add_conf_by_address(CONF_KILL, yy_aconf);
2968 }
2969 }
2970 else
2971 delete_conf_item(yy_conf);
2972
2973 yy_conf = NULL;
2974 yy_aconf = NULL;
2975 }
2976 };
2977
2978 kill_type: TYPE
2979 {
2980 } '=' kill_type_items ';';
2981
2982 kill_type_items: kill_type_items ',' kill_type_item | kill_type_item;
2983 kill_type_item: REGEX_T
2984 {
2985 if (conf_parser_ctx.pass == 2)
2986 regex_ban = 1;
2987 };
2988
2989 kill_items: kill_items kill_item | kill_item;
2990 kill_item: kill_user | kill_reason | kill_type | error;
2991
2992 kill_user: USER '=' QSTRING ';'
2993 {
2994 if (conf_parser_ctx.pass == 2)
2995 {
2996 struct split_nuh_item nuh;
2997
2998 nuh.nuhmask = yylval.string;
2999 nuh.nickptr = NULL;
3000 nuh.userptr = userbuf;
3001 nuh.hostptr = hostbuf;
3002
3003 nuh.nicksize = 0;
3004 nuh.usersize = sizeof(userbuf);
3005 nuh.hostsize = sizeof(hostbuf);
3006
3007 split_nuh(&nuh);
3008 }
3009 };
3010
3011 kill_reason: REASON '=' QSTRING ';'
3012 {
3013 if (conf_parser_ctx.pass == 2)
3014 strlcpy(reasonbuf, yylval.string, sizeof(reasonbuf));
3015 };
3016
3017 /***************************************************************************
3018 * section deny
3019 ***************************************************************************/
3020 deny_entry: DENY
3021 {
3022 if (conf_parser_ctx.pass == 2)
3023 {
3024 yy_conf = make_conf_item(DLINE_TYPE);
3025 yy_aconf = map_to_conf(yy_conf);
3026 /* default reason */
3027 DupString(yy_aconf->reason, "No reason");
3028 }
3029 } '{' deny_items '}' ';'
3030 {
3031 if (conf_parser_ctx.pass == 2)
3032 {
3033 if (yy_aconf->host && parse_netmask(yy_aconf->host, NULL, NULL) != HM_HOST)
3034 add_conf_by_address(CONF_DLINE, yy_aconf);
3035 else
3036 delete_conf_item(yy_conf);
3037 yy_conf = NULL;
3038 yy_aconf = NULL;
3039 }
3040 };
3041
3042 deny_items: deny_items deny_item | deny_item;
3043 deny_item: deny_ip | deny_reason | error;
3044
3045 deny_ip: IP '=' QSTRING ';'
3046 {
3047 if (conf_parser_ctx.pass == 2)
3048 {
3049 MyFree(yy_aconf->host);
3050 DupString(yy_aconf->host, yylval.string);
3051 }
3052 };
3053
3054 deny_reason: REASON '=' QSTRING ';'
3055 {
3056 if (conf_parser_ctx.pass == 2)
3057 {
3058 MyFree(yy_aconf->reason);
3059 DupString(yy_aconf->reason, yylval.string);
3060 }
3061 };
3062
3063 /***************************************************************************
3064 * section exempt
3065 ***************************************************************************/
3066 exempt_entry: EXEMPT '{' exempt_items '}' ';';
3067
3068 exempt_items: exempt_items exempt_item | exempt_item;
3069 exempt_item: exempt_ip | error;
3070
3071 exempt_ip: IP '=' QSTRING ';'
3072 {
3073 if (conf_parser_ctx.pass == 2)
3074 {
3075 if (yylval.string[0] && parse_netmask(yylval.string, NULL, NULL) != HM_HOST)
3076 {
3077 yy_conf = make_conf_item(EXEMPTDLINE_TYPE);
3078 yy_aconf = map_to_conf(yy_conf);
3079 DupString(yy_aconf->host, yylval.string);
3080
3081 add_conf_by_address(CONF_EXEMPTDLINE, yy_aconf);
3082
3083 yy_conf = NULL;
3084 yy_aconf = NULL;
3085 }
3086 }
3087 };
3088
3089 /***************************************************************************
3090 * section gecos
3091 ***************************************************************************/
3092 gecos_entry: GECOS
3093 {
3094 if (conf_parser_ctx.pass == 2)
3095 {
3096 regex_ban = 0;
3097 reasonbuf[0] = gecos_name[0] = '\0';
3098 }
3099 } '{' gecos_items '}' ';'
3100 {
3101 if (conf_parser_ctx.pass == 2)
3102 {
3103 if (gecos_name[0])
3104 {
3105 if (regex_ban)
3106 {
3107 pcre *exp_p = NULL;
3108 const char *errptr = NULL;
3109
3110 if (!(exp_p = ircd_pcre_compile(gecos_name, &errptr)))
3111 {
3112 ilog(L_ERROR, "Failed to add regular expression based X-Line: %s",
3113 errptr);
3114 break;
3115 }
3116
3117 yy_conf = make_conf_item(RXLINE_TYPE);
3118 yy_conf->regexpname = exp_p;
3119 }
3120 else
3121 yy_conf = make_conf_item(XLINE_TYPE);
3122
3123 yy_match_item = map_to_conf(yy_conf);
3124 DupString(yy_conf->name, gecos_name);
3125
3126 if (reasonbuf[0])
3127 DupString(yy_match_item->reason, reasonbuf);
3128 else
3129 DupString(yy_match_item->reason, "No reason");
3130 }
3131 }
3132 };
3133
3134 gecos_flags: TYPE
3135 {
3136 } '=' gecos_flags_items ';';
3137
3138 gecos_flags_items: gecos_flags_items ',' gecos_flags_item | gecos_flags_item;
3139 gecos_flags_item: REGEX_T
3140 {
3141 if (conf_parser_ctx.pass == 2)
3142 regex_ban = 1;
3143 };
3144
3145 gecos_items: gecos_items gecos_item | gecos_item;
3146 gecos_item: gecos_name | gecos_reason | gecos_flags | error;
3147
3148 gecos_name: NAME '=' QSTRING ';'
3149 {
3150 if (conf_parser_ctx.pass == 2)
3151 strlcpy(gecos_name, yylval.string, sizeof(gecos_name));
3152 };
3153
3154 gecos_reason: REASON '=' QSTRING ';'
3155 {
3156 if (conf_parser_ctx.pass == 2)
3157 strlcpy(reasonbuf, yylval.string, sizeof(reasonbuf));
3158 };
3159
3160 /***************************************************************************
3161 * section general
3162 ***************************************************************************/
3163 general_entry: GENERAL
3164 '{' general_items '}' ';';
3165
3166 general_items: general_items general_item | general_item;
3167 general_item: general_hide_spoof_ips | general_ignore_bogus_ts |
3168 general_failed_oper_notice | general_anti_nick_flood |
3169 general_max_nick_time | general_max_nick_changes |
3170 general_max_accept | general_anti_spam_exit_message_time |
3171 general_ts_warn_delta | general_ts_max_delta |
3172 general_kill_chase_time_limit | general_kline_with_reason |
3173 general_kline_reason | general_invisible_on_connect |
3174 general_warn_no_nline | general_dots_in_ident |
3175 general_stats_o_oper_only | general_stats_k_oper_only |
3176 general_pace_wait | general_stats_i_oper_only |
3177 general_pace_wait_simple | general_stats_P_oper_only |
3178 general_short_motd | general_no_oper_flood |
3179 general_true_no_oper_flood | general_oper_pass_resv |
3180 general_idletime | general_message_locale |
3181 general_oper_only_umodes | general_max_targets |
3182 general_use_egd | general_egdpool_path |
3183 general_oper_umodes | general_caller_id_wait |
3184 general_opers_bypass_callerid | general_default_floodcount |
3185 general_min_nonwildcard | general_min_nonwildcard_simple |
3186 general_servlink_path | general_disable_remote_commands |
3187 general_default_cipher_preference |
3188 general_compression_level | general_client_flood |
3189 general_throttle_time | general_havent_read_conf |
3190 general_dot_in_ip6_addr | general_ping_cookie |
3191 general_disable_auth | general_burst_away |
3192 general_tkline_expire_notices | general_gline_min_cidr |
3193 general_gline_min_cidr6 | general_use_whois_actually |
3194 general_reject_hold_time | general_stats_e_disabled |
3195 general_max_watch |
3196 error;
3197
3198
3199 general_max_watch: MAX_WATCH '=' NUMBER ';'
3200 {
3201 ConfigFileEntry.max_watch = $3;
3202 };
3203
3204 general_gline_min_cidr: GLINE_MIN_CIDR '=' NUMBER ';'
3205 {
3206 ConfigFileEntry.gline_min_cidr = $3;
3207 };
3208
3209 general_gline_min_cidr6: GLINE_MIN_CIDR6 '=' NUMBER ';'
3210 {
3211 ConfigFileEntry.gline_min_cidr6 = $3;
3212 };
3213
3214 general_burst_away: BURST_AWAY '=' TBOOL ';'
3215 {
3216 ConfigFileEntry.burst_away = yylval.number;
3217 };
3218
3219 general_use_whois_actually: USE_WHOIS_ACTUALLY '=' TBOOL ';'
3220 {
3221 ConfigFileEntry.use_whois_actually = yylval.number;
3222 };
3223
3224 general_reject_hold_time: TREJECT_HOLD_TIME '=' timespec ';'
3225 {
3226 GlobalSetOptions.rejecttime = yylval.number;
3227 };
3228
3229 general_tkline_expire_notices: TKLINE_EXPIRE_NOTICES '=' TBOOL ';'
3230 {
3231 ConfigFileEntry.tkline_expire_notices = yylval.number;
3232 };
3233
3234 general_kill_chase_time_limit: KILL_CHASE_TIME_LIMIT '=' NUMBER ';'
3235 {
3236 ConfigFileEntry.kill_chase_time_limit = $3;
3237 };
3238
3239 general_hide_spoof_ips: HIDE_SPOOF_IPS '=' TBOOL ';'
3240 {
3241 ConfigFileEntry.hide_spoof_ips = yylval.number;
3242 };
3243
3244 general_ignore_bogus_ts: IGNORE_BOGUS_TS '=' TBOOL ';'
3245 {
3246 ConfigFileEntry.ignore_bogus_ts = yylval.number;
3247 };
3248
3249 general_disable_remote_commands: DISABLE_REMOTE_COMMANDS '=' TBOOL ';'
3250 {
3251 ConfigFileEntry.disable_remote = yylval.number;
3252 };
3253
3254 general_failed_oper_notice: FAILED_OPER_NOTICE '=' TBOOL ';'
3255 {
3256 ConfigFileEntry.failed_oper_notice = yylval.number;
3257 };
3258
3259 general_anti_nick_flood: ANTI_NICK_FLOOD '=' TBOOL ';'
3260 {
3261 ConfigFileEntry.anti_nick_flood = yylval.number;
3262 };
3263
3264 general_max_nick_time: MAX_NICK_TIME '=' timespec ';'
3265 {
3266 ConfigFileEntry.max_nick_time = $3;
3267 };
3268
3269 general_max_nick_changes: MAX_NICK_CHANGES '=' NUMBER ';'
3270 {
3271 ConfigFileEntry.max_nick_changes = $3;
3272 };
3273
3274 general_max_accept: MAX_ACCEPT '=' NUMBER ';'
3275 {
3276 ConfigFileEntry.max_accept = $3;
3277 };
3278
3279 general_anti_spam_exit_message_time: ANTI_SPAM_EXIT_MESSAGE_TIME '=' timespec ';'
3280 {
3281 ConfigFileEntry.anti_spam_exit_message_time = $3;
3282 };
3283
3284 general_ts_warn_delta: TS_WARN_DELTA '=' timespec ';'
3285 {
3286 ConfigFileEntry.ts_warn_delta = $3;
3287 };
3288
3289 general_ts_max_delta: TS_MAX_DELTA '=' timespec ';'
3290 {
3291 if (conf_parser_ctx.pass == 2)
3292 ConfigFileEntry.ts_max_delta = $3;
3293 };
3294
3295 general_havent_read_conf: HAVENT_READ_CONF '=' NUMBER ';'
3296 {
3297 if (($3 > 0) && conf_parser_ctx.pass == 1)
3298 {
3299 ilog(L_CRIT, "You haven't read your config file properly.");
3300 ilog(L_CRIT, "There is a line in the example conf that will kill your server if not removed.");
3301 ilog(L_CRIT, "Consider actually reading/editing the conf file, and removing this line.");
3302 exit(0);
3303 }
3304 };
3305
3306 general_kline_with_reason: KLINE_WITH_REASON '=' TBOOL ';'
3307 {
3308 ConfigFileEntry.kline_with_reason = yylval.number;
3309 };
3310
3311 general_kline_reason: KLINE_REASON '=' QSTRING ';'
3312 {
3313 if (conf_parser_ctx.pass == 2)
3314 {
3315 MyFree(ConfigFileEntry.kline_reason);
3316 DupString(ConfigFileEntry.kline_reason, yylval.string);
3317 }
3318 };
3319
3320 general_invisible_on_connect: INVISIBLE_ON_CONNECT '=' TBOOL ';'
3321 {
3322 ConfigFileEntry.invisible_on_connect = yylval.number;
3323 };
3324
3325 general_warn_no_nline: WARN_NO_NLINE '=' TBOOL ';'
3326 {
3327 ConfigFileEntry.warn_no_nline = yylval.number;
3328 };
3329
3330 general_stats_e_disabled: STATS_E_DISABLED '=' TBOOL ';'
3331 {
3332 ConfigFileEntry.stats_e_disabled = yylval.number;
3333 };
3334
3335 general_stats_o_oper_only: STATS_O_OPER_ONLY '=' TBOOL ';'
3336 {
3337 ConfigFileEntry.stats_o_oper_only = yylval.number;
3338 };
3339
3340 general_stats_P_oper_only: STATS_P_OPER_ONLY '=' TBOOL ';'
3341 {
3342 ConfigFileEntry.stats_P_oper_only = yylval.number;
3343 };
3344
3345 general_stats_k_oper_only: STATS_K_OPER_ONLY '=' TBOOL ';'
3346 {
3347 ConfigFileEntry.stats_k_oper_only = 2 * yylval.number;
3348 } | STATS_K_OPER_ONLY '=' TMASKED ';'
3349 {
3350 ConfigFileEntry.stats_k_oper_only = 1;
3351 };
3352
3353 general_stats_i_oper_only: STATS_I_OPER_ONLY '=' TBOOL ';'
3354 {
3355 ConfigFileEntry.stats_i_oper_only = 2 * yylval.number;
3356 } | STATS_I_OPER_ONLY '=' TMASKED ';'
3357 {
3358 ConfigFileEntry.stats_i_oper_only = 1;
3359 };
3360
3361 general_pace_wait: PACE_WAIT '=' timespec ';'
3362 {
3363 ConfigFileEntry.pace_wait = $3;
3364 };
3365
3366 general_caller_id_wait: CALLER_ID_WAIT '=' timespec ';'
3367 {
3368 ConfigFileEntry.caller_id_wait = $3;
3369 };
3370
3371 general_opers_bypass_callerid: OPERS_BYPASS_CALLERID '=' TBOOL ';'
3372 {
3373 ConfigFileEntry.opers_bypass_callerid = yylval.number;
3374 };
3375
3376 general_pace_wait_simple: PACE_WAIT_SIMPLE '=' timespec ';'
3377 {
3378 ConfigFileEntry.pace_wait_simple = $3;
3379 };
3380
3381 general_short_motd: SHORT_MOTD '=' TBOOL ';'
3382 {
3383 ConfigFileEntry.short_motd = yylval.number;
3384 };
3385
3386 general_no_oper_flood: NO_OPER_FLOOD '=' TBOOL ';'
3387 {
3388 ConfigFileEntry.no_oper_flood = yylval.number;
3389 };
3390
3391 general_true_no_oper_flood: TRUE_NO_OPER_FLOOD '=' TBOOL ';'
3392 {
3393 ConfigFileEntry.true_no_oper_flood = yylval.number;
3394 };
3395
3396 general_oper_pass_resv: OPER_PASS_RESV '=' TBOOL ';'
3397 {
3398 ConfigFileEntry.oper_pass_resv = yylval.number;
3399 };
3400
3401 general_message_locale: MESSAGE_LOCALE '=' QSTRING ';'
3402 {
3403 if (conf_parser_ctx.pass == 2)
3404 {
3405 if (strlen(yylval.string) > LOCALE_LENGTH-2)
3406 yylval.string[LOCALE_LENGTH-1] = '\0';
3407
3408 set_locale(yylval.string);
3409 }
3410 };
3411
3412 general_idletime: IDLETIME '=' timespec ';'
3413 {
3414 ConfigFileEntry.idletime = $3;
3415 };
3416
3417 general_dots_in_ident: DOTS_IN_IDENT '=' NUMBER ';'
3418 {
3419 ConfigFileEntry.dots_in_ident = $3;
3420 };
3421
3422 general_max_targets: MAX_TARGETS '=' NUMBER ';'
3423 {
3424 ConfigFileEntry.max_targets = $3;
3425 };
3426
3427 general_servlink_path: SERVLINK_PATH '=' QSTRING ';'
3428 {
3429 if (conf_parser_ctx.pass == 2)
3430 {
3431 MyFree(ConfigFileEntry.servlink_path);
3432 DupString(ConfigFileEntry.servlink_path, yylval.string);
3433 }
3434 };
3435
3436 general_default_cipher_preference: DEFAULT_CIPHER_PREFERENCE '=' QSTRING ';'
3437 {
3438 #ifdef HAVE_LIBCRYPTO
3439 if (conf_parser_ctx.pass == 2)
3440 {
3441 struct EncCapability *ecap;
3442 const char *cipher_name;
3443 int found = 0;
3444
3445 ConfigFileEntry.default_cipher_preference = NULL;
3446 cipher_name = yylval.string;
3447
3448 for (ecap = CipherTable; ecap->name; ecap++)
3449 {
3450 if ((irccmp(ecap->name, cipher_name) == 0) &&
3451 (ecap->cap & CAP_ENC_MASK))
3452 {
3453 ConfigFileEntry.default_cipher_preference = ecap;
3454 found = 1;
3455 break;
3456 }
3457 }
3458
3459 if (!found)
3460 yyerror("Invalid cipher");
3461 }
3462 #else
3463 if (conf_parser_ctx.pass == 2)
3464 yyerror("Ignoring default_cipher_preference -- no OpenSSL support");
3465 #endif
3466 };
3467
3468 general_compression_level: COMPRESSION_LEVEL '=' NUMBER ';'
3469 {
3470 if (conf_parser_ctx.pass == 2)
3471 {
3472 ConfigFileEntry.compression_level = $3;
3473 #ifndef HAVE_LIBZ
3474 yyerror("Ignoring compression_level -- no zlib support");
3475 #else
3476 if ((ConfigFileEntry.compression_level < 1) ||
3477 (ConfigFileEntry.compression_level > 9))
3478 {
3479 yyerror("Ignoring invalid compression_level, using default");
3480 ConfigFileEntry.compression_level = 0;
3481 }
3482 #endif
3483 }
3484 };
3485
3486 general_use_egd: USE_EGD '=' TBOOL ';'
3487 {
3488 ConfigFileEntry.use_egd = yylval.number;
3489 };
3490
3491 general_egdpool_path: EGDPOOL_PATH '=' QSTRING ';'
3492 {
3493 if (conf_parser_ctx.pass == 2)
3494 {
3495 MyFree(ConfigFileEntry.egdpool_path);
3496 DupString(ConfigFileEntry.egdpool_path, yylval.string);
3497 }
3498 };
3499
3500 general_ping_cookie: PING_COOKIE '=' TBOOL ';'
3501 {
3502 ConfigFileEntry.ping_cookie = yylval.number;
3503 };
3504
3505 general_disable_auth: DISABLE_AUTH '=' TBOOL ';'
3506 {
3507 ConfigFileEntry.disable_auth = yylval.number;
3508 };
3509
3510 general_throttle_time: THROTTLE_TIME '=' timespec ';'
3511 {
3512 ConfigFileEntry.throttle_time = yylval.number;
3513 };
3514
3515 general_oper_umodes: OPER_UMODES
3516 {
3517 ConfigFileEntry.oper_umodes = 0;
3518 } '=' umode_oitems ';' ;
3519
3520 umode_oitems: umode_oitems ',' umode_oitem | umode_oitem;
3521 umode_oitem: T_BOTS
3522 {
3523 ConfigFileEntry.oper_umodes |= UMODE_BOTS;
3524 } | T_CCONN
3525 {
3526 ConfigFileEntry.oper_umodes |= UMODE_CCONN;
3527 } | T_CCONN_FULL
3528 {
3529 ConfigFileEntry.oper_umodes |= UMODE_CCONN_FULL;
3530 } | T_DEAF
3531 {
3532 ConfigFileEntry.oper_umodes |= UMODE_DEAF;
3533 } | T_DEBUG
3534 {
3535 ConfigFileEntry.oper_umodes |= UMODE_DEBUG;
3536 } | T_FULL
3537 {
3538 ConfigFileEntry.oper_umodes |= UMODE_FULL;
3539 } | T_SKILL
3540 {
3541 ConfigFileEntry.oper_umodes |= UMODE_SKILL;
3542 } | T_NCHANGE
3543 {
3544 ConfigFileEntry.oper_umodes |= UMODE_NCHANGE;
3545 } | T_REJ
3546 {
3547 ConfigFileEntry.oper_umodes |= UMODE_REJ;
3548 } | T_UNAUTH
3549 {
3550 ConfigFileEntry.oper_umodes |= UMODE_UNAUTH;
3551 } | T_SPY
3552 {
3553 ConfigFileEntry.oper_umodes |= UMODE_SPY;
3554 } | T_EXTERNAL
3555 {
3556 ConfigFileEntry.oper_umodes |= UMODE_EXTERNAL;
3557 } | T_OPERWALL
3558 {
3559 ConfigFileEntry.oper_umodes |= UMODE_OPERWALL;
3560 } | T_SERVNOTICE
3561 {
3562 ConfigFileEntry.oper_umodes |= UMODE_SERVNOTICE;
3563 } | T_INVISIBLE
3564 {
3565 ConfigFileEntry.oper_umodes |= UMODE_INVISIBLE;
3566 } | T_WALLOP
3567 {
3568 ConfigFileEntry.oper_umodes |= UMODE_WALLOP;
3569 } | T_SOFTCALLERID
3570 {
3571 ConfigFileEntry.oper_umodes |= UMODE_SOFTCALLERID;
3572 } | T_CALLERID
3573 {
3574 ConfigFileEntry.oper_umodes |= UMODE_CALLERID;
3575 } | T_LOCOPS
3576 {
3577 ConfigFileEntry.oper_umodes |= UMODE_LOCOPS;
3578 };
3579
3580 general_oper_only_umodes: OPER_ONLY_UMODES
3581 {
3582 ConfigFileEntry.oper_only_umodes = 0;
3583 } '=' umode_items ';' ;
3584
3585 umode_items: umode_items ',' umode_item | umode_item;
3586 umode_item: T_BOTS
3587 {
3588 ConfigFileEntry.oper_only_umodes |= UMODE_BOTS;
3589 } | T_CCONN
3590 {
3591 ConfigFileEntry.oper_only_umodes |= UMODE_CCONN;
3592 } | T_CCONN_FULL
3593 {
3594 ConfigFileEntry.oper_only_umodes |= UMODE_CCONN_FULL;
3595 } | T_DEAF
3596 {
3597 ConfigFileEntry.oper_only_umodes |= UMODE_DEAF;
3598 } | T_DEBUG
3599 {
3600 ConfigFileEntry.oper_only_umodes |= UMODE_DEBUG;
3601 } | T_FULL
3602 {
3603 ConfigFileEntry.oper_only_umodes |= UMODE_FULL;
3604 } | T_SKILL
3605 {
3606 ConfigFileEntry.oper_only_umodes |= UMODE_SKILL;
3607 } | T_NCHANGE
3608 {
3609 ConfigFileEntry.oper_only_umodes |= UMODE_NCHANGE;
3610 } | T_REJ
3611 {
3612 ConfigFileEntry.oper_only_umodes |= UMODE_REJ;
3613 } | T_UNAUTH
3614 {
3615 ConfigFileEntry.oper_only_umodes |= UMODE_UNAUTH;
3616 } | T_SPY
3617 {
3618 ConfigFileEntry.oper_only_umodes |= UMODE_SPY;
3619 } | T_EXTERNAL
3620 {
3621 ConfigFileEntry.oper_only_umodes |= UMODE_EXTERNAL;
3622 } | T_OPERWALL
3623 {
3624 ConfigFileEntry.oper_only_umodes |= UMODE_OPERWALL;
3625 } | T_SERVNOTICE
3626 {
3627 ConfigFileEntry.oper_only_umodes |= UMODE_SERVNOTICE;
3628 } | T_INVISIBLE
3629 {
3630 ConfigFileEntry.oper_only_umodes |= UMODE_INVISIBLE;
3631 } | T_WALLOP
3632 {
3633 ConfigFileEntry.oper_only_umodes |= UMODE_WALLOP;
3634 } | T_SOFTCALLERID
3635 {
3636 ConfigFileEntry.oper_only_umodes |= UMODE_SOFTCALLERID;
3637 } | T_CALLERID
3638 {
3639 ConfigFileEntry.oper_only_umodes |= UMODE_CALLERID;
3640 } | T_LOCOPS
3641 {
3642 ConfigFileEntry.oper_only_umodes |= UMODE_LOCOPS;
3643 };
3644
3645 general_min_nonwildcard: MIN_NONWILDCARD '=' NUMBER ';'
3646 {
3647 ConfigFileEntry.min_nonwildcard = $3;
3648 };
3649
3650 general_min_nonwildcard_simple: MIN_NONWILDCARD_SIMPLE '=' NUMBER ';'
3651 {
3652 ConfigFileEntry.min_nonwildcard_simple = $3;
3653 };
3654
3655 general_default_floodcount: DEFAULT_FLOODCOUNT '=' NUMBER ';'
3656 {
3657 ConfigFileEntry.default_floodcount = $3;
3658 };
3659
3660 general_client_flood: T_CLIENT_FLOOD '=' sizespec ';'
3661 {
3662 ConfigFileEntry.client_flood = $3;
3663 };
3664
3665 general_dot_in_ip6_addr: DOT_IN_IP6_ADDR '=' TBOOL ';'
3666 {
3667 ConfigFileEntry.dot_in_ip6_addr = yylval.number;
3668 };
3669
3670 /***************************************************************************
3671 * section glines
3672 ***************************************************************************/
3673 gline_entry: GLINES
3674 {
3675 if (conf_parser_ctx.pass == 2)
3676 {
3677 yy_conf = make_conf_item(GDENY_TYPE);
3678 yy_aconf = map_to_conf(yy_conf);
3679 }
3680 } '{' gline_items '}' ';'
3681 {
3682 if (conf_parser_ctx.pass == 2)
3683 {
3684 /*
3685 * since we re-allocate yy_conf/yy_aconf after the end of action=, at the
3686 * end we will have one extra, so we should free it.
3687 */
3688 if (yy_conf->name == NULL || yy_aconf->user == NULL)
3689 {
3690 delete_conf_item(yy_conf);
3691 yy_conf = NULL;
3692 yy_aconf = NULL;
3693 }
3694 }
3695 };
3696
3697 gline_items: gline_items gline_item | gline_item;
3698 gline_item: gline_enable |
3699 gline_duration |
3700 gline_logging |
3701 gline_user |
3702 gline_server |
3703 gline_action |
3704 error;
3705
3706 gline_enable: ENABLE '=' TBOOL ';'
3707 {
3708 if (conf_parser_ctx.pass == 2)
3709 ConfigFileEntry.glines = yylval.number;
3710 };
3711
3712 gline_duration: DURATION '=' timespec ';'
3713 {
3714 if (conf_parser_ctx.pass == 2)
3715 ConfigFileEntry.gline_time = $3;
3716 };
3717
3718 gline_logging: LOGGING
3719 {
3720 if (conf_parser_ctx.pass == 2)
3721 ConfigFileEntry.gline_logging = 0;
3722 } '=' gline_logging_types ';';
3723 gline_logging_types: gline_logging_types ',' gline_logging_type_item | gline_logging_type_item;
3724 gline_logging_type_item: T_REJECT
3725 {
3726 if (conf_parser_ctx.pass == 2)
3727 ConfigFileEntry.gline_logging |= GDENY_REJECT;
3728 } | T_BLOCK
3729 {
3730 if (conf_parser_ctx.pass == 2)
3731 ConfigFileEntry.gline_logging |= GDENY_BLOCK;
3732 };
3733
3734 gline_user: USER '=' QSTRING ';'
3735 {
3736 if (conf_parser_ctx.pass == 2)
3737 {
3738 struct split_nuh_item nuh;
3739
3740 nuh.nuhmask = yylval.string;
3741 nuh.nickptr = NULL;
3742 nuh.userptr = userbuf;
3743 nuh.hostptr = hostbuf;
3744
3745 nuh.nicksize = 0;
3746 nuh.usersize = sizeof(userbuf);
3747 nuh.hostsize = sizeof(hostbuf);
3748
3749 split_nuh(&nuh);
3750
3751 if (yy_aconf->user == NULL)
3752 {
3753 DupString(yy_aconf->user, userbuf);
3754 DupString(yy_aconf->host, hostbuf);
3755 }
3756 else
3757 {
3758 struct CollectItem *yy_tmp = MyMalloc(sizeof(struct CollectItem));
3759
3760 DupString(yy_tmp->user, userbuf);
3761 DupString(yy_tmp->host, hostbuf);
3762
3763 dlinkAdd(yy_tmp, &yy_tmp->node, &col_conf_list);
3764 }
3765 }
3766 };
3767
3768 gline_server: NAME '=' QSTRING ';'
3769 {
3770 if (conf_parser_ctx.pass == 2)
3771 {
3772 MyFree(yy_conf->name);
3773 DupString(yy_conf->name, yylval.string);
3774 }
3775 };
3776
3777 gline_action: ACTION
3778 {
3779 if (conf_parser_ctx.pass == 2)
3780 yy_aconf->flags = 0;
3781 } '=' gdeny_types ';'
3782 {
3783 if (conf_parser_ctx.pass == 2)
3784 {
3785 struct CollectItem *yy_tmp = NULL;
3786 dlink_node *ptr, *next_ptr;
3787
3788 DLINK_FOREACH_SAFE(ptr, next_ptr, col_conf_list.head)
3789 {
3790 struct AccessItem *new_aconf;
3791 struct ConfItem *new_conf;
3792
3793 yy_tmp = ptr->data;
3794 new_conf = make_conf_item(GDENY_TYPE);
3795 new_aconf = map_to_conf(new_conf);
3796
3797 new_aconf->flags = yy_aconf->flags;
3798
3799 if (yy_conf->name != NULL)
3800 DupString(new_conf->name, yy_conf->name);
3801 else
3802 DupString(new_conf->name, "*");
3803 if (yy_aconf->user != NULL)
3804 DupString(new_aconf->user, yy_tmp->user);
3805 else
3806 DupString(new_aconf->user, "*");
3807 if (yy_aconf->host != NULL)
3808 DupString(new_aconf->host, yy_tmp->host);
3809 else
3810 DupString(new_aconf->host, "*");
3811
3812 dlinkDelete(&yy_tmp->node, &col_conf_list);
3813 }
3814
3815 /*
3816 * In case someone has fed us with more than one action= after user/name
3817 * which would leak memory -Michael
3818 */
3819 if (yy_conf->name == NULL || yy_aconf->user == NULL)
3820 delete_conf_item(yy_conf);
3821
3822 yy_conf = make_conf_item(GDENY_TYPE);
3823 yy_aconf = map_to_conf(yy_conf);
3824 }
3825 };
3826
3827 gdeny_types: gdeny_types ',' gdeny_type_item | gdeny_type_item;
3828 gdeny_type_item: T_REJECT
3829 {
3830 if (conf_parser_ctx.pass == 2)
3831 yy_aconf->flags |= GDENY_REJECT;
3832 } | T_BLOCK
3833 {
3834 if (conf_parser_ctx.pass == 2)
3835 yy_aconf->flags |= GDENY_BLOCK;
3836 };
3837
3838 /***************************************************************************
3839 * section channel
3840 ***************************************************************************/
3841 channel_entry: CHANNEL
3842 '{' channel_items '}' ';';
3843
3844 channel_items: channel_items channel_item | channel_item;
3845 channel_item: channel_disable_local_channels | channel_use_except |
3846 channel_use_invex | channel_use_knock |
3847 channel_max_bans | channel_knock_delay |
3848 channel_knock_delay_channel | channel_max_chans_per_user |
3849 channel_quiet_on_ban | channel_default_split_user_count |
3850 channel_default_split_server_count |
3851 channel_no_create_on_split | channel_restrict_channels |
3852 channel_no_join_on_split | channel_burst_topicwho |
3853 channel_jflood_count | channel_jflood_time |
3854 channel_disable_fake_channels | error;
3855
3856 channel_disable_fake_channels: DISABLE_FAKE_CHANNELS '=' TBOOL ';'
3857 {
3858 ConfigChannel.disable_fake_channels = yylval.number;
3859 };
3860
3861 channel_restrict_channels: RESTRICT_CHANNELS '=' TBOOL ';'
3862 {
3863 ConfigChannel.restrict_channels = yylval.number;
3864 };
3865
3866 channel_disable_local_channels: DISABLE_LOCAL_CHANNELS '=' TBOOL ';'
3867 {
3868 ConfigChannel.disable_local_channels = yylval.number;
3869 };
3870
3871 channel_use_except: USE_EXCEPT '=' TBOOL ';'
3872 {
3873 ConfigChannel.use_except = yylval.number;
3874 };
3875
3876 channel_use_invex: USE_INVEX '=' TBOOL ';'
3877 {
3878 ConfigChannel.use_invex = yylval.number;
3879 };
3880
3881 channel_use_knock: USE_KNOCK '=' TBOOL ';'
3882 {
3883 ConfigChannel.use_knock = yylval.number;
3884 };
3885
3886 channel_knock_delay: KNOCK_DELAY '=' timespec ';'
3887 {
3888 ConfigChannel.knock_delay = $3;
3889 };
3890
3891 channel_knock_delay_channel: KNOCK_DELAY_CHANNEL '=' timespec ';'
3892 {
3893 ConfigChannel.knock_delay_channel = $3;
3894 };
3895
3896 channel_max_chans_per_user: MAX_CHANS_PER_USER '=' NUMBER ';'
3897 {
3898 ConfigChannel.max_chans_per_user = $3;
3899 };
3900
3901 channel_quiet_on_ban: QUIET_ON_BAN '=' TBOOL ';'
3902 {
3903 ConfigChannel.quiet_on_ban = yylval.number;
3904 };
3905
3906 channel_max_bans: MAX_BANS '=' NUMBER ';'
3907 {
3908 ConfigChannel.max_bans = $3;
3909 };
3910
3911 channel_default_split_user_count: DEFAULT_SPLIT_USER_COUNT '=' NUMBER ';'
3912 {
3913 ConfigChannel.default_split_user_count = $3;
3914 };
3915
3916 channel_default_split_server_count: DEFAULT_SPLIT_SERVER_COUNT '=' NUMBER ';'
3917 {
3918 ConfigChannel.default_split_server_count = $3;
3919 };
3920
3921 channel_no_create_on_split: NO_CREATE_ON_SPLIT '=' TBOOL ';'
3922 {
3923 ConfigChannel.no_create_on_split = yylval.number;
3924 };
3925
3926 channel_no_join_on_split: NO_JOIN_ON_SPLIT '=' TBOOL ';'
3927 {
3928 ConfigChannel.no_join_on_split = yylval.number;
3929 };
3930
3931 channel_burst_topicwho: BURST_TOPICWHO '=' TBOOL ';'
3932 {
3933 ConfigChannel.burst_topicwho = yylval.number;
3934 };
3935
3936 channel_jflood_count: JOIN_FLOOD_COUNT '=' NUMBER ';'
3937 {
3938 GlobalSetOptions.joinfloodcount = yylval.number;
3939 };
3940
3941 channel_jflood_time: JOIN_FLOOD_TIME '=' timespec ';'
3942 {
3943 GlobalSetOptions.joinfloodtime = yylval.number;
3944 };
3945
3946 /***************************************************************************
3947 * section serverhide
3948 ***************************************************************************/
3949 serverhide_entry: SERVERHIDE
3950 '{' serverhide_items '}' ';';
3951
3952 serverhide_items: serverhide_items serverhide_item | serverhide_item;
3953 serverhide_item: serverhide_flatten_links | serverhide_hide_servers |
3954 serverhide_links_delay |
3955 serverhide_disable_hidden |
3956 serverhide_hidden | serverhide_hidden_name |
3957 serverhide_hide_server_ips |
3958 error;
3959
3960 serverhide_flatten_links: FLATTEN_LINKS '=' TBOOL ';'
3961 {
3962 if (conf_parser_ctx.pass == 2)
3963 ConfigServerHide.flatten_links = yylval.number;
3964 };
3965
3966 serverhide_hide_servers: HIDE_SERVERS '=' TBOOL ';'
3967 {
3968 if (conf_parser_ctx.pass == 2)
3969 ConfigServerHide.hide_servers = yylval.number;
3970 };
3971
3972 serverhide_hidden_name: HIDDEN_NAME '=' QSTRING ';'
3973 {
3974 if (conf_parser_ctx.pass == 2)
3975 {
3976 MyFree(ConfigServerHide.hidden_name);
3977 DupString(ConfigServerHide.hidden_name, yylval.string);
3978 }
3979 };
3980
3981 serverhide_links_delay: LINKS_DELAY '=' timespec ';'
3982 {
3983 if (conf_parser_ctx.pass == 2)
3984 {
3985 if (($3 > 0) && ConfigServerHide.links_disabled == 1)
3986 {
3987 eventAddIsh("write_links_file", write_links_file, NULL, $3);
3988 ConfigServerHide.links_disabled = 0;
3989 }
3990
3991 ConfigServerHide.links_delay = $3;
3992 }
3993 };
3994
3995 serverhide_hidden: HIDDEN '=' TBOOL ';'
3996 {
3997 if (conf_parser_ctx.pass == 2)
3998 ConfigServerHide.hidden = yylval.number;
3999 };
4000
4001 serverhide_disable_hidden: DISABLE_HIDDEN '=' TBOOL ';'
4002 {
4003 if (conf_parser_ctx.pass == 2)
4004 ConfigServerHide.disable_hidden = yylval.number;
4005 };
4006
4007 serverhide_hide_server_ips: HIDE_SERVER_IPS '=' TBOOL ';'
4008 {
4009 if (conf_parser_ctx.pass == 2)
4010 ConfigServerHide.hide_server_ips = yylval.number;
4011 };

Properties

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