Bez tytułu

z k4be, 5 lata temu, napisane w C, wyświetlone 477 razy.
URL https://pastebin.k4be.pl/view/95031789 Udostępnij
Pobierz wklejkę lub Pokaż surowy tekst
  1. /* Copyright (C) All Rights Reserved
  2. ** Written by Gottem <support@gottem.nl>
  3. ** Website: https://gitgud.malvager.net/Wazakindjes/unrealircd_mods
  4. ** License: https://gitgud.malvager.net/Wazakindjes/unrealircd_mods/raw/master/LICENSE
  5. **
  6. ** Contains edits by k4be to implement a fake channel list
  7. */
  8.  
  9. // One include for all cross-platform compatibility thangs
  10. #include "unrealircd.h"
  11.  
  12. #define MYCONF "listrestrict"
  13. #define OVR_LIST "LIST"
  14. #define OVR_JOIN "JOIN"
  15.  
  16. #define FCHAN_DEFUSERS 2 // Let 2 users be the default for a fake channel
  17. #define FCHAN_DEFTOPIC "DO NOT JOIN" // Also topic
  18.  
  19. #define LR_DELAYFAIL(x) (muhDelay > 0 && (x)->local && TStime() - (x)->local->firsttime < muhDelay)
  20. #define LR_AUTHFAIL(x) (needAuth && !IsLoggedIn((x)))
  21.  
  22. // Big hecks go here
  23. typedef enum {
  24.         LRE_ALL = 0,
  25.         LRE_CONNECT = 1,
  26.         LRE_AUTH = 2,
  27.         LRE_FAKECHANS = 3,
  28. } exceptType;
  29.  
  30. typedef struct t_restrictex restrictExcept;
  31. struct t_restrictex {
  32.         exceptType type;
  33.         char *mask;
  34.         restrictExcept *next;
  35. };
  36.  
  37. typedef struct t_fakechans fakeChannel;
  38. struct t_fakechans {
  39.         char *name;
  40.         char *topic;
  41.         int users;
  42.         unsigned short glinem;
  43.         fakeChannel *next;
  44. };
  45.  
  46. // Quality fowod declarations
  47. void checkem_exceptions(aClient *sptr, unsigned short *connect, unsigned short *auth, unsigned short *fakechans);
  48. static int listrestrict_overridelist(Cmdoverride *ovr, aClient *cptr, aClient *sptr, int parc, char *parv[]);
  49. static int listrestrict_overridejoin(Cmdoverride *ovr, aClient *cptr, aClient *sptr, int parc, char *parv[]);
  50. int listrestrict_configtest(ConfigFile *cf, ConfigEntry *ce, int type, int *errs);
  51. int listrestrict_configposttest(int *errs);
  52. int listrestrict_configrun(ConfigFile *cf, ConfigEntry *ce, int type);
  53. int listrestrict_rehash(void);
  54.  
  55. // Muh globals
  56. static ModuleInfo *lrestrictMI = NULL; // Store ModuleInfo so we can use it to check for errors in MOD_LOAD
  57. Cmdoverride *lrestrictOVRList, *lrestrictOVRJoin; // Pointer to the overrides we're gonna add
  58. restrictExcept *exceptList = NULL; // Stores exceptions yo
  59. fakeChannel *fakechanList = NULL; // Also fake channels
  60. int fakechanCount = 0;
  61. unsigned short conf_fakechans = 0;
  62. unsigned short conf_exemptIdents = 0;
  63.  
  64. // Deez defaults
  65. int muhDelay = 0; // Default to off yo
  66. unsigned short needAuth = 0; // Must be identified w/ NickServ (in addition to passing the delay check)
  67. unsigned short fakeChans = 0; // Send fake channels list
  68. unsigned short authIsEnough = 0; // Only NickServ auth is enough to be exempt
  69. unsigned short exemptIdents = 0; // Users without ~ at the beginning of their username are exempt from list restrictions
  70. time_t glineTime = 86400; // Default to 1 day
  71.  
  72. // Dat dere module header
  73. ModuleHeader MOD_HEADER(m_listrestrict) = {
  74.         "m_listrestrict", // Module name
  75.         "$Id: v1.04 2018/11/04 Gottem/k4be$", // Version
  76.         "Impose certain restrictions on /LIST usage", // Description
  77.         "3.2-b8-1", // Modversion, not sure wat do
  78.         NULL
  79. };
  80.  
  81. // Configuration testing-related hewks go in testing phase obv
  82. MOD_TEST(m_listrestrict) {
  83.         // We have our own config block so we need to checkem config obv m9
  84.         // Priorities don't really matter here
  85.         HookAdd(modinfo->handle, HOOKTYPE_CONFIGTEST, 0, listrestrict_configtest);
  86.         HookAdd(modinfo->handle, HOOKTYPE_CONFIGPOSTTEST, 0, listrestrict_configposttest);
  87.         return MOD_SUCCESS;
  88. }
  89.  
  90. // Initialisation routine (register hooks, commands and modes or create structs etc)
  91. MOD_INIT(m_listrestrict) {
  92.         lrestrictMI = modinfo; // Store module info yo
  93.  
  94.         // Muh config hewks
  95.         HookAdd(modinfo->handle, HOOKTYPE_REHASH, 0, listrestrict_rehash);
  96.         HookAdd(modinfo->handle, HOOKTYPE_CONFIGRUN, 0, listrestrict_configrun);
  97.  
  98.         return MOD_SUCCESS; // Let MOD_LOAD handle errors and shyte
  99. }
  100.  
  101. // Actually load the module here
  102. MOD_LOAD(m_listrestrict) {
  103.         // Attempt to add command overrides
  104.         lrestrictOVRList = CmdoverrideAdd(lrestrictMI->handle, OVR_LIST, listrestrict_overridelist);
  105.         lrestrictOVRJoin = CmdoverrideAdd(lrestrictMI->handle, OVR_JOIN, listrestrict_overridejoin);
  106.  
  107.         // Check if module handle is available, also check for hooks that weren't added for some raisin
  108.         if(ModuleGetError(lrestrictMI->handle) != MODERR_NOERROR || !lrestrictOVRList || !lrestrictOVRJoin) {
  109.                 // Display error string kek
  110.                 config_error("A critical error occurred when loading module %s: %s", MOD_HEADER(m_listrestrict).name, ModuleGetErrorStr(lrestrictMI->handle));
  111.                 return MOD_FAILED; // No good
  112.         }
  113. /*      if(conf_exemptIdents && !IDENT_CHECK){
  114.                 config_error("[%s] %s::exemptidents was enabled but your config does not enable set::options::identd-check. The m_listrestrict would fail to work with this configuration.", MOD_HEADER(m_listrestrict).name, MYCONF);
  115.                 return MOD_FAILED; // No good
  116.         }*/ // here it does not display the error at first start
  117.         return MOD_SUCCESS; // We good
  118. }
  119.  
  120. // Called on unload/rehash obv
  121. MOD_UNLOAD(m_listrestrict) {
  122.         if(exceptList) {
  123.                 // This shit is a bit convoluted to prevent memory issues obv famalmalmalmlmalm
  124.                 restrictExcept *exEntry;
  125.                 while((exEntry = exceptList) != NULL) {
  126.                         exceptList = exceptList->next;
  127.                         if(exEntry->mask) free(exEntry->mask);
  128.                         free(exEntry);
  129.                 }
  130.                 exceptList = NULL;
  131.         }
  132.  
  133.         if(fakechanList) {
  134.                 // This shit is a bit convoluted to prevent memory issues obv famalmalmalmlmalm
  135.                 fakeChannel *fchanEntry;
  136.                 while((fchanEntry = fakechanList) != NULL) {
  137.                         fakechanList = fakechanList->next;
  138.                         if(fchanEntry->name) free(fchanEntry->name);
  139.                         if(fchanEntry->topic) free(fchanEntry->topic);
  140.                         free(fchanEntry);
  141.                 }
  142.                 fakechanList = NULL;
  143.         }
  144.         fakechanCount = 0;
  145.  
  146.         return MOD_SUCCESS; // We good
  147. }
  148.  
  149. void checkem_exceptions(aClient *sptr, unsigned short *connect, unsigned short *auth, unsigned short *fakechans) {
  150.         restrictExcept *exEntry; // For iteration yo
  151.         for(exEntry = exceptList; exEntry; exEntry = exEntry->next) {
  152.                 if(!match(exEntry->mask, make_user_host(sptr->user->username, sptr->user->realhost)) || !match(exEntry->mask, make_user_host(sptr->user->username, sptr->ip))) {
  153.                         switch(exEntry->type) {
  154.                                 case LRE_ALL:
  155.                                         *connect = 1;
  156.                                         *auth = 1;
  157.                                         *fakechans = 1;
  158.                                         break;
  159.                                 case LRE_CONNECT:
  160.                                         *connect = 1;
  161.                                         break;
  162.                                 case LRE_AUTH:
  163.                                         *auth = 1;
  164.                                         break;
  165.                                 case LRE_FAKECHANS:
  166.                                         *fakechans = 1;
  167.                                         break;
  168.                                 default:
  169.                                         break;
  170.                         }
  171.                         // Keep checking entries to support just whitelisting 2 instead of 1 or all ;]
  172.                 }
  173.         }
  174.         if(authIsEnough && (*auth || IsLoggedIn(sptr)))
  175.                 *connect = 1;
  176.         if(exemptIdents && sptr->user && sptr->user->username[0] != '~'){
  177.                 *connect = 1;
  178.                 *auth = 1;
  179.                 *fakechans = 1;
  180.         }
  181. }
  182.  
  183. // Now for the actual override
  184. static int listrestrict_overridelist(Cmdoverride *ovr, aClient *cptr, aClient *sptr, int parc, char *parv[]) {
  185.         /* Gets args: Cmdoverride *ovr, aClient *cptr, aClient *sptr, int parc, char *parv[]
  186.         **
  187.         ** ovr: Pointer to the override we're attached to
  188.         ** cptr: Pointer to directly attached client -- if remote user this is the remote server instead
  189.         ** sptr: Pointer to user executing command
  190.         ** parc: Amount of arguments (also includes the command in the count)
  191.         ** parv: Contains the actual args, first one starts at parv[1]
  192.         **
  193.         ** So "LIST test" would result in parc = 2 and parv[1] = "test"
  194.         ** Also, parv[0] seems to always be NULL, so better not rely on it fam
  195.         */
  196.         fakeChannel *fchanEntry; // For iteration yo
  197.         unsigned short except_connect; // We gottem exception?
  198.         unsigned short except_auth; // Ditt0
  199.         unsigned short except_fakechans;
  200.         unsigned short delayFail;
  201.         unsigned short authFail;
  202.         unsigned short fakechanFail;
  203.  
  204.         // Checkem exceptions bro
  205.         except_connect = 0;
  206.         except_auth = 0;
  207.         except_fakechans = 0;
  208.         if(!MyConnect(sptr) || !IsPerson(sptr) || IsOper(sptr) || IsULine(sptr)) { // Default set lel
  209.                 except_connect = 1;
  210.                 except_auth = 1;
  211.                 except_fakechans = 1;
  212.         }
  213.         else // Not an oper/U:Line/server, checkem whitelist (if ne)
  214.                 checkem_exceptions(sptr, &except_connect, &except_auth, &except_fakechans);
  215.  
  216.         delayFail = (!except_connect && LR_DELAYFAIL(sptr)); // Sanity check + delay check =]
  217.         authFail = (!except_auth && LR_AUTHFAIL(sptr)); // Need identified check ;];;]
  218.         fakechanFail = (!except_fakechans && fakeChans);
  219.  
  220.         // Send fake list if necessary
  221.         if(fakechanFail && (delayFail || authFail)) {
  222.                 sendto_one(sptr, rpl_str(RPL_LISTSTART), me.name, sptr->name);
  223.                 for(fchanEntry = fakechanList; fchanEntry; fchanEntry = fchanEntry->next)
  224.                         sendto_one(sptr, rpl_str(RPL_LIST), me.name, sptr->name, fchanEntry->name, fchanEntry->users, "[+ntr]", fchanEntry->topic);
  225.                 sendto_one(sptr, rpl_str(RPL_LISTEND), me.name, sptr->name);
  226.         }
  227.  
  228.         if(delayFail) {
  229.                 sendnotice(sptr, "You have to be connected for at least %d seconds before being able to /%s%s", muhDelay, OVR_LIST, (fakechanFail ? ", please ignore the fake output above" : ""));
  230.                 return 0;
  231.         }
  232.  
  233.         if(authFail) {
  234.                 sendnotice(sptr, "You have to be identified with services before being able to /%s%s", OVR_LIST, (fakechanFail ? ", please ignore the fake output above" : ""));
  235.                 return 0;
  236.         }
  237.  
  238.         return CallCmdoverride(ovr, cptr, sptr, parc, parv); // Run original function yo
  239. }
  240.  
  241. static int listrestrict_overridejoin(Cmdoverride *ovr, aClient *cptr, aClient *sptr, int parc, char *parv[]) {
  242.         // Doing the G:Line thing in an override too so we run _before_ the channel is actually created, plus we need to return FLUSH_BUFFER
  243.         // which isn't supported by HOOKTYPE_PRE_LOCAL_JOIN and might crash shit =]
  244.         fakeChannel *fchanEntry;
  245.         unsigned short except_connect;
  246.         unsigned short except_auth;
  247.         unsigned short except_fakechans;
  248.         unsigned short delayFail;
  249.         unsigned short authFail;
  250.         unsigned short fakechanFail;
  251.         unsigned short glinem;
  252.         char *chan, *tmp, *p; // Pointers for getting multiple channel names
  253.  
  254.         // Only act on local joins etc
  255.         if(BadPtr(parv[1]) || !MyConnect(sptr) || !IsPerson(sptr) || IsOper(sptr) || IsULine(sptr) || !fakeChans)
  256.                 return CallCmdoverride(ovr, cptr, sptr, parc, parv); // Run original function yo
  257.  
  258.         glinem = 0;
  259.         tmp = strdup(parv[1]);
  260.         for(chan = strtoken(&p, tmp, ","); !glinem && chan; chan = strtoken(&p, NULL, ",")) {
  261.                 for(fchanEntry = fakechanList; fchanEntry; fchanEntry = fchanEntry->next) {
  262.                         if(chan && !stricmp(chan, fchanEntry->name)) {
  263.                                 // Should only be one channel per unique name, so break regardless of gline flag
  264.                                 if(fchanEntry->glinem)
  265.                                         glinem = 1;
  266.                                 break;
  267.                         }
  268.                 }
  269.         }
  270.         free(tmp);
  271.  
  272.         // Check if we got an entry matching this channel AND the gline flag is enabled
  273.         if(!fchanEntry || !glinem)
  274.                 return CallCmdoverride(ovr, cptr, sptr, parc, parv);
  275.  
  276.         except_connect = 0;
  277.         except_auth = 0;
  278.         except_fakechans = 0;
  279.         checkem_exceptions(sptr, &except_connect, &except_auth, &except_fakechans);
  280.         delayFail = (!except_connect && LR_DELAYFAIL(sptr));
  281.         authFail = (!except_auth && LR_AUTHFAIL(sptr));
  282.         fakechanFail = (!except_fakechans);
  283.  
  284.         // Place ban if necessary =]
  285.         if(fakechanFail && (delayFail || authFail))
  286.                 return place_host_ban(sptr, BAN_ACT_GLINE, "Invalid channel", glineTime);
  287.         return CallCmdoverride(ovr, cptr, sptr, parc, parv);
  288. }
  289.  
  290. int listrestrict_configtest(ConfigFile *cf, ConfigEntry *ce, int type, int *errs) {
  291.         ConfigEntry *cep, *cep2; // For looping through our bl0cc, nested
  292.         int errors = 0; // Error count
  293.         int i; // iter8or m8
  294.         int have_fchanname;
  295.  
  296.         // Since we'll add a new top-level block to unrealircd.conf, need to filter on CONFIG_MAIN lmao
  297.         if(type != CONFIG_MAIN)
  298.                 return 0; // Returning 0 means idgaf bout dis
  299.  
  300.         // Check for valid config entries first
  301.         if(!ce || !ce->ce_varname)
  302.                 return 0;
  303.  
  304.         // If it isn't our bl0ck, idc
  305.         if(strcmp(ce->ce_varname, MYCONF))
  306.                 return 0;
  307.  
  308.         // Loop dat shyte fam
  309.         for(cep = ce->ce_entries; cep; cep = cep->ce_next) {
  310.                 // Do we even have a valid name l0l?
  311.                 if(!cep->ce_varname) {
  312.                         config_error("%s:%i: blank %s item", cep->ce_fileptr->cf_filename, cep->ce_varlinenum, MYCONF); // Rep0t error
  313.                         errors++; // Increment err0r count fam
  314.                         continue; // Next iteration imo tbh
  315.                 }
  316.  
  317.                 if(!strcmp(cep->ce_varname, "connectdelay")) {
  318.                         if(!cep->ce_vardata) {
  319.                                 config_error("%s:%i: %s::%s must be an integer of 10 or larger m8", cep->ce_fileptr->cf_filename, cep->ce_varlinenum, MYCONF, cep->ce_varname);
  320.                                 errors++; // Increment err0r count fam
  321.                                 continue; // Next iteration imo tbh
  322.                         }
  323.                         // Should be an integer yo
  324.                         for(i = 0; cep->ce_vardata[i]; i++) {
  325.                                 if(!isdigit(cep->ce_vardata[i])) {
  326.                                         config_error("%s:%i: %s::%s must be an integer of 10 or larger m8", cep->ce_fileptr->cf_filename, cep->ce_varlinenum, MYCONF, cep->ce_varname);
  327.                                         errors++; // Increment err0r count fam
  328.                                         break;
  329.                                 }
  330.                         }
  331.                         if(!errors && atoi(cep->ce_vardata) < 10) {
  332.                                 config_error("%s:%i: %s::%s must be an integer of 10 or larger m8", cep->ce_fileptr->cf_filename, cep->ce_varlinenum, MYCONF, cep->ce_varname);
  333.                                 errors++; // Increment err0r count fam
  334.                         }
  335.                         continue;
  336.                 }
  337.  
  338.                 if(!strcmp(cep->ce_varname, "needauth")) {
  339.                         if(!cep->ce_vardata || (strcmp(cep->ce_vardata, "0") && strcmp(cep->ce_vardata, "1"))) {
  340.                                 config_error("%s:%i: %s::%s must be either 0 or 1 fam", cep->ce_fileptr->cf_filename, cep->ce_varlinenum, MYCONF, cep->ce_varname);
  341.                                 errors++; // Increment err0r count fam
  342.                         }
  343.                         continue;
  344.                 }
  345.  
  346.                 if(!strcmp(cep->ce_varname, "authisenough")) {
  347.                         if(!cep->ce_vardata || (strcmp(cep->ce_vardata, "0") && strcmp(cep->ce_vardata, "1"))) {
  348.                                 config_error("%s:%i: %s::%s must be either 0 or 1 fam", cep->ce_fileptr->cf_filename, cep->ce_varlinenum, MYCONF, cep->ce_varname);
  349.                                 errors++; // Increment err0r count fam
  350.                         }
  351.                         continue;
  352.                 }
  353.  
  354.                 if(!strcmp(cep->ce_varname, "fakechans")) {
  355.                         if(!cep->ce_vardata || (strcmp(cep->ce_vardata, "0") && strcmp(cep->ce_vardata, "1"))) {
  356.                                 config_error("%s:%i: %s::%s must be either 0 or 1 fam", cep->ce_fileptr->cf_filename, cep->ce_varlinenum, MYCONF, cep->ce_varname);
  357.                                 errors++; // Increment err0r count fam
  358.                         }
  359.                         else
  360.                                 conf_fakechans = atoi(cep->ce_vardata);
  361.                         continue;
  362.                 }
  363.                
  364.                 if(!strcmp(cep->ce_varname, "exemptidents")) {
  365.                         if(!cep->ce_vardata || (strcmp(cep->ce_vardata, "0") && strcmp(cep->ce_vardata, "1"))) {
  366.                                 config_error("%s:%i: %s::%s must be either 0 or 1 fam", cep->ce_fileptr->cf_filename, cep->ce_varlinenum, MYCONF, cep->ce_varname);
  367.                                 errors++; // Increment err0r count fam
  368.                         }
  369.                         else
  370.                                 conf_exemptIdents = atoi(cep->ce_vardata);
  371.                         continue;
  372.                 }
  373.  
  374.                 if(!strcmp(cep->ce_varname, "glinetime")) {
  375.                         // Should be a time string imo (7d10s etc, or just 20)
  376.                         if(!cep->ce_vardata || config_checkval(cep->ce_vardata, CFG_TIME) <= 0) {
  377.                                 config_error("%s:%i: %s::%s must be a time string like '7d10m' or simply '20'", cep->ce_fileptr->cf_filename, cep->ce_varlinenum, MYCONF, cep->ce_varname);
  378.                                 errors++; // Increment err0r count fam
  379.                         }
  380.                         continue;
  381.                 }
  382.  
  383.                 // Here comes a nested block =]
  384.                 if(!strcmp(cep->ce_varname, "exceptions")) {
  385.                         // Loop 'em again
  386.                         for(cep2 = cep->ce_entries; cep2; cep2 = cep2->ce_next) {
  387.                                 if(!cep2->ce_varname || !cep2->ce_vardata) {
  388.                                         config_error("%s:%i: blank/incomplete %s::exceptions entry", cep2->ce_fileptr->cf_filename, cep2->ce_varlinenum, MYCONF); // Rep0t error
  389.                                         errors++; // Increment err0r count fam
  390.                                         continue; // Next iteration imo tbh
  391.                                 }
  392.  
  393.                                 if(strcmp(cep2->ce_varname, "all") && strcmp(cep2->ce_varname, "connect") && strcmp(cep2->ce_varname, "auth") && strcmp(cep2->ce_varname, "fakechans")) {
  394.                                         config_error("%s:%i: invalid %s::exceptions type (must be one of: connect, auth, fakechans, all)", cep2->ce_fileptr->cf_filename, cep2->ce_varlinenum, MYCONF); // Rep0t error
  395.                                         errors++; // Increment err0r count fam
  396.                                         continue; // Next iteration imo tbh
  397.                                 }
  398.  
  399.                                 if(!match("*!*@*", cep2->ce_vardata) || match("*@*", cep2->ce_vardata) || strlen(cep2->ce_vardata) < 3) {
  400.                                         config_error("%s:%i: invalid %s::exceptions mask (must be of the format ident@hostip)", cep2->ce_fileptr->cf_filename, cep2->ce_varlinenum, MYCONF); // Rep0t error
  401.                                         errors++; // Increment err0r count fam
  402.                                         continue; // Next iteration imo tbh
  403.                                 }
  404.                         }
  405.                         continue;
  406.                 }
  407.  
  408.                 // Here comes another nested block =]
  409.                 if(!strcmp(cep->ce_varname, "fakechannel")) {
  410.                         have_fchanname = 0;
  411.                         for(cep2 = cep->ce_entries; cep2; cep2 = cep2->ce_next) {
  412.                                 if(!cep2->ce_varname || !cep2->ce_vardata) {
  413.                                         config_error("%s:%i: blank/incomplete %s::fakechannel entry", cep2->ce_fileptr->cf_filename, cep2->ce_varlinenum, MYCONF); // Rep0t error
  414.                                         errors++; // Increment err0r count fam
  415.                                         continue; // Next iteration imo tbh
  416.                                 }
  417.  
  418.                                 if(strcmp(cep2->ce_varname, "name") && strcmp(cep2->ce_varname, "topic") && strcmp(cep2->ce_varname, "users") && strcmp(cep2->ce_varname, "gline")) {
  419.                                         config_error("%s:%i: invalid %s::fakechannel attribute (must be one of: name, topic, users, gline)", cep2->ce_fileptr->cf_filename, cep2->ce_varlinenum, MYCONF); // Rep0t error
  420.                                         errors++; // Increment err0r count fam
  421.                                         continue; // Next iteration imo tbh
  422.                                 }
  423.  
  424.                                 if(!strcmp(cep2->ce_varname, "name")) {
  425.                                         have_fchanname = 1;
  426.                                         if(cep2->ce_vardata[0] != '#') {
  427.                                                 config_error("%s:%i: invalid %s::fakechannel::%s (channel name must start with a #)", cep2->ce_fileptr->cf_filename, cep2->ce_varlinenum, MYCONF, cep2->ce_varname); // Rep0t error
  428.                                                 errors++;
  429.                                                 continue;
  430.                                         }
  431.                                         if(strchr(cep2->ce_vardata, ',') || strchr(cep2->ce_vardata, ' ')) {
  432.                                                 config_error("%s:%i: invalid %s::fakechannel::%s (contains space or comma)", cep2->ce_fileptr->cf_filename, cep2->ce_varlinenum, MYCONF, cep2->ce_varname); // Rep0t error
  433.                                                 errors++;
  434.                                                 continue;
  435.                                         }
  436.                                         if(strlen(cep2->ce_vardata) > CHANNELLEN) {
  437.                                                 config_error("%s:%i: invalid %s::fakechannel::%s (too long), max length is %i characters", cep2->ce_fileptr->cf_filename, cep2->ce_varlinenum, MYCONF, cep2->ce_varname, CHANNELLEN); // Rep0t error
  438.                                                 errors++;
  439.                                                 continue;
  440.                                         }
  441.                                 }
  442.  
  443.                                 if(!strcmp(cep2->ce_varname, "topic")) {
  444.                                         if(strlen(cep2->ce_vardata) > TOPICLEN) {
  445.                                                 config_error("%s:%i: invalid %s::fakechannel::%s (too long), max length is %i characters", cep2->ce_fileptr->cf_filename, cep2->ce_varlinenum, MYCONF, cep2->ce_varname, TOPICLEN); // Rep0t error
  446.                                                 errors++;
  447.                                                 continue;
  448.                                         }
  449.                                 }
  450.  
  451.                                 if(!strcmp(cep2->ce_varname, "users")) {
  452.                                         if(!cep2->ce_vardata) {
  453.                                                 config_error("%s:%i: %s::fakechannel::%s must be an integer of 1 or larger m8", cep2->ce_fileptr->cf_filename, cep2->ce_varlinenum, MYCONF, cep2->ce_varname);
  454.                                                 errors++; // Increment err0r count fam
  455.                                                 continue;
  456.                                         }
  457.                                         for(i = 0; cep2->ce_vardata[i]; i++) {
  458.                                                 if(!isdigit(cep2->ce_vardata[i])) {
  459.                                                         config_error("%s:%i: %s::fakechannel::%s must be an integer of 1 or larger m8", cep2->ce_fileptr->cf_filename, cep2->ce_varlinenum, MYCONF, cep2->ce_varname);
  460.                                                         errors++; // Increment err0r count fam
  461.                                                         break;
  462.                                                 }
  463.                                         }
  464.                                         if(!errors && atoi(cep2->ce_vardata) < 1) {
  465.                                                 config_error("%s:%i: %s::fakechannel::%s must be an integer of 1 or larger m8", cep2->ce_fileptr->cf_filename, cep2->ce_varlinenum, MYCONF, cep2->ce_varname);
  466.                                                 errors++; // Increment err0r count fam
  467.                                         }
  468.                                         continue;
  469.                                 }
  470.  
  471.                                 if(!strcmp(cep2->ce_varname, "gline")) {
  472.                                         if(!cep2->ce_vardata || (strcmp(cep2->ce_vardata, "0") && strcmp(cep2->ce_vardata, "1"))) {
  473.                                                 config_error("%s:%i: %s::fakechannel::%s must be either 0 or 1 fam", cep2->ce_fileptr->cf_filename, cep2->ce_varlinenum, MYCONF, cep2->ce_varname);
  474.                                                 errors++; // Increment err0r count fam
  475.                                         }
  476.                                         continue;
  477.                                 }
  478.                         }
  479.                         if(!have_fchanname) {
  480.                                 config_error("%s:%i: invalid %s::fakechannel entry (must contain a channel name)", cep->ce_fileptr->cf_filename, cep->ce_varlinenum, MYCONF); // Rep0t error
  481.                                 errors++;
  482.                                 continue;
  483.                         }
  484.                         fakechanCount++;
  485.                         continue;
  486.                 }
  487.  
  488.                 // Anything else is unknown to us =]
  489.                 config_warn("%s:%i: unknown item %s::%s", cep->ce_fileptr->cf_filename, cep->ce_varlinenum, MYCONF, cep->ce_varname); // So display just a warning
  490.         }
  491.  
  492.         *errs = errors;
  493.         return errors ? -1 : 1; // Returning 1 means "all good", -1 means we shat our panties
  494. }
  495.  
  496. int listrestrict_configposttest(int *errs) {
  497.         int errors = 0;
  498.         if(conf_fakechans && !fakechanCount) {
  499.                 config_error("[%s] %s::fakechans was enabled but there aren't any configured channels (fakechannel {} block)", MOD_HEADER(m_listrestrict).name, MYCONF);
  500.                 errors++;
  501.         }
  502. /*      if(conf_exemptIdents && !IDENT_CHECK){
  503.                 config_error("[%s] %s::exemptidents was enabled but your config does not enable set::options::identd-check. The m_listrestrict would fail to work with this configuration.", MOD_HEADER(m_listrestrict).name, MYCONF);
  504.                 errors++;
  505.         }*/ // for some reason this always fails when first starting the ircd
  506.         *errs = errors;
  507.         return errors ? -1 : 1;
  508. }
  509.  
  510. // "Run" the config (everything should be valid at this point)
  511. int listrestrict_configrun(ConfigFile *cf, ConfigEntry *ce, int type) {
  512.         ConfigEntry *cep, *cep2; // For looping through our bl0cc, nested
  513.         restrictExcept *exLast = NULL; // Initialise to NULL so the loop requires minimal l0gic
  514.         fakeChannel *fchanLast = NULL;
  515.         restrictExcept **exEntry = &exceptList; // Hecks so the ->next chain stays intact
  516.         fakeChannel **fchanEntry = &fakechanList;
  517.         exceptType etype;
  518.         char fchanName[BUFSIZE]; // Array instead of pointer for cleaning channel names, cuz we shouldn't modify a strdup()'d pointer directly ;]
  519.         char *fchanTopic;
  520.         int fchanUsers;
  521.         int fchanGlinem;
  522.  
  523.         // Since we'll add a new top-level block to unrealircd.conf, need to filter on CONFIG_MAIN lmao
  524.         if(type != CONFIG_MAIN)
  525.                 return 0; // Returning 0 means idgaf bout dis
  526.  
  527.         // Check for valid config entries first
  528.         if(!ce || !ce->ce_varname)
  529.                 return 0;
  530.  
  531.         // If it isn't our bl0cc, idc
  532.         if(strcmp(ce->ce_varname, MYCONF))
  533.                 return 0;
  534.  
  535.         // Loop dat shyte fam
  536.         for(cep = ce->ce_entries; cep; cep = cep->ce_next) {
  537.                 // Do we even have a valid name l0l?
  538.                 if(!cep->ce_varname)
  539.                         continue; // Next iteration imo tbh
  540.  
  541.                 if(cep->ce_vardata && !strcmp(cep->ce_varname, "connectdelay")) {
  542.                         muhDelay = atoi(cep->ce_vardata);
  543.                         continue;
  544.                 }
  545.  
  546.                 if(cep->ce_vardata && !strcmp(cep->ce_varname, "needauth")) {
  547.                         needAuth = atoi(cep->ce_vardata);
  548.                         continue;
  549.                 }
  550.  
  551.                 if(cep->ce_vardata && !strcmp(cep->ce_varname, "authisenough")) {
  552.                         authIsEnough = atoi(cep->ce_vardata);
  553.                         continue;
  554.                 }
  555.  
  556.                 if(cep->ce_vardata && !strcmp(cep->ce_varname, "fakechans")) {
  557.                         fakeChans = atoi(cep->ce_vardata);
  558.                         continue;
  559.                 }
  560.                
  561.                 if(cep->ce_vardata && !strcmp(cep->ce_varname, "exemptidents")) {
  562.                         exemptIdents = atoi(cep->ce_vardata);
  563.                         continue;
  564.                 }
  565.  
  566.                 if(cep->ce_vardata && !strcmp(cep->ce_varname, "glinetime")) {
  567.                         glineTime = config_checkval(cep->ce_vardata, CFG_TIME);
  568.                         continue;
  569.                 }
  570.  
  571.                 if(!strcmp(cep->ce_varname, "exceptions")) {
  572.                         // Loop 'em
  573.                         for(cep2 = cep->ce_entries; cep2; cep2 = cep2->ce_next) {
  574.                                 if(!cep2->ce_varname || !cep2->ce_vardata) // Sanity checks imo
  575.                                         continue; // Next iteration imo tbh
  576.  
  577.                                 if(!strcmp(cep2->ce_varname, "all"))
  578.                                         etype = LRE_ALL;
  579.                                 else if(!strcmp(cep2->ce_varname, "connect"))
  580.                                         etype = LRE_CONNECT;
  581.                                 else if(!strcmp(cep2->ce_varname, "auth"))
  582.                                         etype = LRE_AUTH;
  583.                                 else if(!strcmp(cep2->ce_varname, "fakechans"))
  584.                                         etype = LRE_FAKECHANS;
  585.  
  586.                                 // Allocate mem0ry for the current entry
  587.                                 *exEntry = malloc(sizeof(restrictExcept));
  588.  
  589.                                 // Allocate/initialise shit here
  590.                                 (*exEntry)->mask = strdup(cep2->ce_vardata);
  591.                                 (*exEntry)->next = NULL;
  592.  
  593.                                 // Copy that shit fam
  594.                                 (*exEntry)->type = etype;
  595.  
  596.                                 // Premium linked list fam
  597.                                 if(exLast)
  598.                                         exLast->next = *exEntry;
  599.  
  600.                                 exLast = *exEntry;
  601.                                 exEntry = &(*exEntry)->next;
  602.                         }
  603.                         continue;
  604.                 }
  605.  
  606.                 if(!strcmp(cep->ce_varname, "fakechannel")) {
  607.                         // Gotta reset values imo
  608.                         fchanName[0] = '\0';
  609.                         fchanTopic = NULL;
  610.                         fchanUsers = 0;
  611.                         fchanGlinem = 0;
  612.  
  613.                         // Loop through parameters of a single fakechan
  614.                         for(cep2 = cep->ce_entries; cep2; cep2 = cep2->ce_next) {
  615.                                 if(!cep2->ce_varname || !cep2->ce_vardata) // Sanity checks imo
  616.                                         continue; // Next iteration imo tbh
  617.  
  618.                                 if(!strcmp(cep2->ce_varname, "name")) {
  619.                                         strlcpy(fchanName, cep2->ce_vardata, sizeof(fchanName));
  620.                                         clean_channelname(fchanName);
  621.                                         continue;
  622.                                 }
  623.  
  624.                                 if(!strcmp(cep2->ce_varname, "topic")) {
  625.                                         if(strlen(cep2->ce_vardata) > 0)
  626.                                                 fchanTopic = cep2->ce_vardata;
  627.                                         continue;
  628.                                 }
  629.  
  630.                                 if(!strcmp(cep2->ce_varname, "users")) {
  631.                                         fchanUsers = atoi(cep2->ce_vardata);
  632.                                         continue;
  633.                                 }
  634.  
  635.                                 if(!strcmp(cep2->ce_varname, "gline")) {
  636.                                         fchanGlinem = atoi(cep2->ce_vardata);
  637.                                         continue;
  638.                                 }
  639.                         }
  640.  
  641.                         // Make sure we don't overallocate shit (no topic/users specified is all0wed, only name is required)
  642.                         if(!fchanName[0])
  643.                                 continue;
  644.  
  645.                         // Allocate mem0ry for the current entry
  646.                         *fchanEntry = malloc(sizeof(fakeChannel));
  647.  
  648.                         (*fchanEntry)->name = strdup(fchanName);
  649.                         (*fchanEntry)->topic = (fchanTopic ? strdup(fchanTopic) : strdup(FCHAN_DEFTOPIC));
  650.                         (*fchanEntry)->users = (fchanUsers <= 0 ? FCHAN_DEFUSERS : fchanUsers);
  651.                         (*fchanEntry)->glinem = fchanGlinem;
  652.                         (*fchanEntry)->next = NULL;
  653.  
  654.                         if(fchanLast)
  655.                                 fchanLast->next = *fchanEntry;
  656.  
  657.                         fchanLast = *fchanEntry;
  658.                         fchanEntry = &(*fchanEntry)->next;
  659.                         continue;
  660.                 }
  661.         }
  662.  
  663.         return 1; // We good
  664. }
  665.  
  666. int listrestrict_rehash(void) {
  667.         // Reset config defaults
  668.         muhDelay = 0;
  669.         needAuth = 0;
  670.         fakeChans = 0;
  671.         authIsEnough = 0;
  672.         glineTime = 86400;
  673.         conf_fakechans = 0;
  674.         conf_exemptIdents = 0;
  675.         return HOOK_CONTINUE;
  676. }
  677.  

odpowiedź "Bez tytułu"

Tutaj możesz odpowiedzieć na wklejkę z góry

captcha