unrealircd

- supernets unrealircd source & configuration
git clone git://git.acid.vegas/unrealircd.git
Log | Files | Refs | Archive | README | LICENSE

issued-by-tag.c (4204B)

      1 /*
      2  * unrealircd.org/issued-by message tag (server only)
      3  * Shows who or what actually issued the command.
      4  * (C) Copyright 2023-.. Syzop and The UnrealIRCd Team
      5  * License: GPLv2 or later
      6  */
      7 
      8 #include "unrealircd.h"
      9 
     10 ModuleHeader MOD_HEADER
     11   = {
     12 	"issued-by-tag",
     13 	"6.0",
     14 	"unrealircd.org/issued-by message tag",
     15 	"UnrealIRCd Team",
     16 	"unrealircd-6",
     17 	};
     18 
     19 /* Forward declarations */
     20 int issued_by_mtag_is_ok(Client *client, const char *name, const char *value);
     21 int issued_by_mtag_should_send_to_client(Client *target);
     22 void mtag_inherit_issued_by(Client *client, MessageTag *recv_mtags, MessageTag **mtag_list, const char *signature);
     23 void _mtag_add_issued_by(MessageTag **mtags, Client *client, MessageTag *recv_mtags);
     24 
     25 MOD_TEST()
     26 {
     27 	MARK_AS_OFFICIAL_MODULE(modinfo);
     28 	EfunctionAddVoid(modinfo->handle, EFUNC_MTAG_GENERATE_ISSUED_BY_IRC, _mtag_add_issued_by);
     29 	return MOD_SUCCESS;
     30 }
     31 
     32 MOD_INIT()
     33 {
     34 	MessageTagHandlerInfo mtag;
     35 
     36 	MARK_AS_OFFICIAL_MODULE(modinfo);
     37 
     38 	memset(&mtag, 0, sizeof(mtag));
     39 	mtag.name = "unrealircd.org/issued-by";
     40 	mtag.is_ok = issued_by_mtag_is_ok;
     41 	mtag.should_send_to_client = issued_by_mtag_should_send_to_client;
     42 	mtag.flags = MTAG_HANDLER_FLAGS_NO_CAP_NEEDED;
     43 	MessageTagHandlerAdd(modinfo->handle, &mtag);
     44 
     45 	HookAddVoid(modinfo->handle, HOOKTYPE_NEW_MESSAGE, 0, mtag_inherit_issued_by);
     46 
     47 	return MOD_SUCCESS;
     48 }
     49 
     50 MOD_LOAD()
     51 {
     52 	return MOD_SUCCESS;
     53 }
     54 
     55 MOD_UNLOAD()
     56 {
     57 	return MOD_SUCCESS;
     58 }
     59 
     60 /** This function verifies if the client sending 'unrealircd.org/issued-by'
     61  * is permitted to do so and uses a permitted syntax.
     62  * We simply allow unrealircd.org/issued-by ONLY from servers and with any syntax.
     63  */
     64 int issued_by_mtag_is_ok(Client *client, const char *name, const char *value)
     65 {
     66 	if (IsServer(client))
     67 		return 1;
     68 
     69 	return 0;
     70 }
     71 
     72 void mtag_inherit_issued_by(Client *client, MessageTag *recv_mtags, MessageTag **mtag_list, const char *signature)
     73 {
     74 	MessageTag *m = find_mtag(recv_mtags, "unrealircd.org/issued-by");
     75 	if (m)
     76 	{
     77 		m = duplicate_mtag(m);
     78 		AddListItem(m, *mtag_list);
     79 	}
     80 }
     81 
     82 /** Outgoing filter for this message tag */
     83 int issued_by_mtag_should_send_to_client(Client *target)
     84 {
     85 	if (IsServer(target) || IsOper(target))
     86 		return 1;
     87 
     88 	return 0;
     89 }
     90 
     91 /** Add "unrealircd.org/issued-by" tag, if applicable.
     92  * @param mtags		Pointer to the message tags linked list head
     93  * @param client	The client issuing the command, or NULL for none.
     94  * @param recv_mtags	The mtags to inherit from, or NULL for none.
     95  * @notes If specifying both 'client' and 'recv_mtags' then
     96  * if inheritance through 'recv_mtags' takes precedence (if it exists).
     97  *
     98  * Typical usage is:
     99  * For locally generated:
    100  *   mtag_add_issued_by(&mtags, client, NULL);
    101  * For inheriting from remote requests:
    102  *   mtag_add_issued_by(&mtags, NULL, recv_mtags);
    103  * For both, such as if the command is used from RPC:
    104  *   mtag_add_issued_by(&mtags, client, recv_mtags);
    105  */
    106 void _mtag_add_issued_by(MessageTag **mtags, Client *client, MessageTag *recv_mtags)
    107 {
    108 	MessageTag *m;
    109 	char buf[512];
    110 
    111 	m = find_mtag(recv_mtags, "unrealircd.org/issued-by");
    112 	if (m)
    113 	{
    114 		m = duplicate_mtag(m);
    115 		AddListItem(m, *mtags);
    116 		return;
    117 	}
    118 
    119 	if (client == NULL)
    120 		return;
    121 
    122 	if (IsRPC(client) && client->rpc)
    123 	{
    124 		// TODO: test with all of: local rpc through unix socket, local rpc web, RRPC
    125 		if (client->rpc->issuer)
    126 		{
    127 			snprintf(buf, sizeof(buf), "RPC:%s@%s:%s", client->rpc->rpc_user, client->uplink->name, client->rpc->issuer);
    128 		} else {
    129 			snprintf(buf, sizeof(buf), "RPC:%s@%s", client->rpc->rpc_user, client->uplink->name);
    130 		}
    131 	} else
    132 	if (IsULine(client))
    133 	{
    134 		if (IsUser(client))
    135 			snprintf(buf, sizeof(buf), "SERVICES:%s@%s", client->name, client->uplink->name);
    136 		else
    137 			snprintf(buf, sizeof(buf), "SERVICES:%s", client->name);
    138 	} else
    139 	if (IsOper(client))
    140 	{
    141 		const char *operlogin = moddata_client_get(client, "operlogin");
    142 		if (operlogin)
    143 			snprintf(buf, sizeof(buf), "OPER:%s@%s:%s", client->name, client->uplink->name, operlogin);
    144 		else
    145 			snprintf(buf, sizeof(buf), "OPER:%s@%s", client->name, client->uplink->name);
    146 	} else
    147 	{
    148 		return;
    149 	}
    150 
    151 	m = safe_alloc(sizeof(MessageTag));
    152 	safe_strdup(m->name, "unrealircd.org/issued-by");
    153 	safe_strdup(m->value, buf);
    154 	AddListItem(m, *mtags);
    155 }