diff options
-rw-r--r-- | protocols.c | 3 | ||||
-rw-r--r-- | protocols/inspircd2.c | 15 | ||||
-rw-r--r-- | protocols/inspircd3.c | 618 | ||||
-rw-r--r-- | protocols/inspircd3.h | 23 |
4 files changed, 523 insertions, 136 deletions
diff --git a/protocols.c b/protocols.c index bf3959d..269c8f1 100644 --- a/protocols.c +++ b/protocols.c @@ -120,6 +120,7 @@ struct protocol protocols[NUM_PROTOCOLS] = { .propagate_oper_user = inspircd3_protocol_propagate_oper_user, .propagate_set_account = inspircd3_protocol_propagate_set_account, + .propagate_set_cert = inspircd3_protocol_propagate_set_cert, .propagate_set_channel = inspircd3_protocol_propagate_set_channel, .propagate_join_channel = inspircd3_protocol_propagate_join_channel, @@ -139,6 +140,7 @@ struct protocol protocols[NUM_PROTOCOLS] = { .handle_oper_user = inspircd3_protocol_handle_oper_user, .handle_set_account = inspircd3_protocol_handle_set_account, + .handle_set_cert = inspircd3_protocol_handle_set_cert, .handle_set_channel = inspircd3_protocol_handle_set_channel, .handle_join_channel = inspircd3_protocol_handle_join_channel, @@ -152,6 +154,7 @@ struct protocol protocols[NUM_PROTOCOLS] = { .fail_oper_user = inspircd3_protocol_fail_oper_user, .fail_set_account = inspircd3_protocol_fail_set_account, + .fail_set_cert = inspircd3_protocol_fail_set_cert, .fail_set_channel = inspircd3_protocol_fail_set_channel, .fail_join_channel = inspircd3_protocol_fail_join_channel, diff --git a/protocols/inspircd2.c b/protocols/inspircd2.c index 76f85eb..7f9c3f3 100644 --- a/protocols/inspircd2.c +++ b/protocols/inspircd2.c @@ -1020,6 +1020,21 @@ void inspircd2_protocol_introduce_servers_to(size_t net, void *handle) { inspircd2_protocol_introduce_servers_to_inner(net, handle, SID, info); } } + + for (size_t i = 0; i < server_list.len; i++) { + struct server_info *target = server_list.array[i].ptr; + if (target != self && target->protocol != INSPIRCD2_PROTOCOL) { + networks[net].send(handle, STRING(":")); + networks[net].send(handle, SID); + networks[net].send(handle, STRING(" SERVER ")); + networks[net].send(handle, target->name); + networks[net].send(handle, STRING(" * 0 ")); + networks[net].send(handle, target->sid); + networks[net].send(handle, STRING(" :")); + networks[net].send(handle, target->fullname); + networks[net].send(handle, STRING("\n")); + } + } } void inspircd2_protocol_introduce_user_to(size_t net, void *handle, struct user_info *user, char join_channels) { diff --git a/protocols/inspircd3.c b/protocols/inspircd3.c index 19ab187..347b370 100644 --- a/protocols/inspircd3.c +++ b/protocols/inspircd3.c @@ -142,11 +142,17 @@ int init_inspircd3_protocol(void) { set_table_index(&inspircd3_protocol_commands, STRING("OPERTYPE"), &inspircd3_protocol_handle_opertype); set_table_index(&inspircd3_protocol_commands, STRING("FJOIN"), &inspircd3_protocol_handle_fjoin); -// set_table_index(&inspircd3_protocol_commands, STRING("PART"), &inspircd3_protocol_handle_part); -// set_table_index(&inspircd3_protocol_commands, STRING("KICK"), &inspircd3_protocol_handle_kick); -// -// set_table_index(&inspircd3_protocol_commands, STRING("PRIVMSG"), &inspircd3_protocol_handle_privmsg); -// set_table_index(&inspircd3_protocol_commands, STRING("NOTICE"), &inspircd3_protocol_handle_notice); + set_table_index(&inspircd3_protocol_commands, STRING("IJOIN"), &inspircd3_protocol_handle_ijoin); + set_table_index(&inspircd3_protocol_commands, STRING("PART"), &inspircd3_protocol_handle_part); + set_table_index(&inspircd3_protocol_commands, STRING("KICK"), &inspircd3_protocol_handle_kick); + + set_table_index(&inspircd3_protocol_commands, STRING("PRIVMSG"), &inspircd3_protocol_handle_privmsg); + set_table_index(&inspircd3_protocol_commands, STRING("NOTICE"), &inspircd3_protocol_handle_notice); + + set_table_index(&inspircd3_protocol_commands, STRING("MODE"), &inspircd3_protocol_handle_mode); + set_table_index(&inspircd3_protocol_commands, STRING("FMODE"), &inspircd3_protocol_handle_fmode); + + set_table_index(&inspircd3_protocol_commands, STRING("METADATA"), &inspircd3_protocol_handle_metadata); return 0; } @@ -616,14 +622,34 @@ void inspircd3_protocol_propagate_new_user(struct string from, struct user_info } // :source NICK <nick> <timestamp> -void inspircd3_protocol_propagate_rename_user(struct string from, struct user_info *user, struct string nick, size_t timestamp, struct string timestamp_str) { - inspircd3_protocol_propagate(from, STRING(":")); - inspircd3_protocol_propagate(from, user->uid); - inspircd3_protocol_propagate(from, STRING(" NICK ")); - inspircd3_protocol_propagate(from, nick); - inspircd3_protocol_propagate(from, STRING(" ")); - inspircd3_protocol_propagate(from, timestamp_str); - inspircd3_protocol_propagate(from, STRING("\n")); +void inspircd3_protocol_propagate_rename_user(struct string from, struct user_info *user, struct string nick, size_t timestamp, struct string timestamp_str, char forced, char immediate) { + if (forced) { + if (STRING_EQ(user->uid, nick)) { + inspircd3_protocol_propagate(from, STRING(":")); + inspircd3_protocol_propagate(from, user->uid); + inspircd3_protocol_propagate(from, STRING(" SAVE ")); + inspircd3_protocol_propagate(from, user->uid); + inspircd3_protocol_propagate(from, STRING(" :")); + inspircd3_protocol_propagate(from, user->nick_ts_str); + inspircd3_protocol_propagate(from, STRING("\n")); + } else { + inspircd3_protocol_propagate(from, STRING(":")); + inspircd3_protocol_propagate(from, from); + inspircd3_protocol_propagate(from, STRING(" SANICK ")); + inspircd3_protocol_propagate(from, user->uid); + inspircd3_protocol_propagate(from, STRING(" :")); + inspircd3_protocol_propagate(from, nick); + inspircd3_protocol_propagate(from, STRING("\n")); + } + } else { + inspircd3_protocol_propagate(from, STRING(":")); + inspircd3_protocol_propagate(from, user->uid); + inspircd3_protocol_propagate(from, STRING(" NICK ")); + inspircd3_protocol_propagate(from, nick); + inspircd3_protocol_propagate(from, STRING(" ")); + inspircd3_protocol_propagate(from, timestamp_str); + inspircd3_protocol_propagate(from, STRING("\n")); + } } // :source QUIT [<reason>?] @@ -663,6 +689,32 @@ void inspircd3_protocol_propagate_oper_user(struct string from, struct user_info } } +// [:source] METADATA <user> accountname <account> +void inspircd3_protocol_propagate_set_account(struct string from, struct user_info *user, struct string account, struct string source) { + inspircd3_protocol_propagate(from, STRING(":")); + inspircd3_protocol_propagate(from, source); + inspircd3_protocol_propagate(from, STRING(" METADATA ")); + inspircd3_protocol_propagate(from, user->uid); + inspircd3_protocol_propagate(from, STRING(" accountname :")); + inspircd3_protocol_propagate(from, account); + inspircd3_protocol_propagate(from, STRING("\n")); +} + +// [:source] METADATA <user> ssl_cert <vtrsE (none) | vTrse <cert>> +void inspircd3_protocol_propagate_set_cert(struct string from, struct user_info *user, struct string cert, struct string source) { + inspircd3_protocol_propagate(from, STRING(":")); + inspircd3_protocol_propagate(from, source); + inspircd3_protocol_propagate(from, STRING(" METADATA ")); + inspircd3_protocol_propagate(from, user->uid); + if (cert.len != 0) { + inspircd3_protocol_propagate(from, STRING(" ssl_cert :vTrse ")); + inspircd3_protocol_propagate(from, cert); + inspircd3_protocol_propagate(from, STRING("\n")); + } else { + inspircd3_protocol_propagate(from, STRING(" ssl_cert :vtrsE No certificate was found.\n")); + } +} + // [:source] FJOIN <channel> <timestamp> <modes> [<mode args>] <userlist: modes,uid:mid [...]> void inspircd3_protocol_propagate_set_channel(struct string from, struct channel_info *channel, char is_new_server, size_t user_count, struct user_info **users) { inspircd3_protocol_propagate(from, STRING(":")); @@ -675,15 +727,22 @@ void inspircd3_protocol_propagate_set_channel(struct string from, struct channel for (size_t x = 0; x < user_count; x++) { inspircd3_protocol_propagate(from, STRING(",")); inspircd3_protocol_propagate(from, users[x]->uid); - struct server_info *server = get_table_index(user_list, users[x]->uid); - if (STRING_EQ(server->sid, SID) || server->protocol != INSPIRCD3_PROTOCOL) { - inspircd3_protocol_propagate(from, STRING(":0")); - } else { - inspircd3_protocol_propagate(from, STRING(":")); - struct inspircd3_protocol_specific_user *prot_specific = users[x]->protocol_specific[INSPIRCD3_PROTOCOL]; - struct inspircd3_protocol_member_id *member = get_table_index(prot_specific->memberships, channel->name); + + struct server_info *server = get_table_index(server_list, users[x]->server); + + inspircd3_protocol_propagate(from, STRING(":")); + struct inspircd3_protocol_specific_user *prot_specific = users[x]->protocol_specific[INSPIRCD3_PROTOCOL]; + struct inspircd3_protocol_member_id *member; + if (!STRING_EQ(server->sid, SID) && server->protocol == INSPIRCD3_PROTOCOL) + member = get_table_index(prot_specific->memberships, channel->name); + else + member = 0; + + if (member) inspircd3_protocol_propagate(from, member->id_str); - } + else + inspircd3_protocol_propagate(from, STRING("0")); + if (x != user_count - 1) inspircd3_protocol_propagate(from, STRING(" ")); } @@ -702,15 +761,22 @@ void inspircd3_protocol_propagate_join_channel(struct string from, struct channe for (size_t x = 0; x < user_count; x++) { inspircd3_protocol_propagate(from, STRING(",")); inspircd3_protocol_propagate(from, users[x]->uid); - struct server_info *server = get_table_index(user_list, users[x]->uid); - if (STRING_EQ(server->sid, SID) || server->protocol != INSPIRCD3_PROTOCOL) { - inspircd3_protocol_propagate(from, STRING(":0")); - } else { - inspircd3_protocol_propagate(from, STRING(":")); - struct inspircd3_protocol_specific_user *prot_specific = users[x]->protocol_specific[INSPIRCD3_PROTOCOL]; - struct inspircd3_protocol_member_id *member = get_table_index(prot_specific->memberships, channel->name); + + struct server_info *server = get_table_index(server_list, users[x]->server); + + inspircd3_protocol_propagate(from, STRING(":")); + struct inspircd3_protocol_specific_user *prot_specific = users[x]->protocol_specific[INSPIRCD3_PROTOCOL]; + struct inspircd3_protocol_member_id *member; + if (!STRING_EQ(server->sid, SID) && server->protocol == INSPIRCD3_PROTOCOL) + member = get_table_index(prot_specific->memberships, channel->name); + else + member = 0; + + if (member) inspircd3_protocol_propagate(from, member->id_str); - } + else + inspircd3_protocol_propagate(from, STRING("0")); + if (x != user_count - 1) inspircd3_protocol_propagate(from, STRING(" ")); } @@ -843,7 +909,7 @@ int inspircd3_protocol_handle_new_user(struct string from, struct user_info *inf return 0; } -int inspircd3_protocol_handle_rename_user(struct string from, struct user_info *info, struct string nick, size_t timestamp, struct string timestamp_str) { +int inspircd3_protocol_handle_rename_user(struct string from, struct user_info *info, struct string nick, size_t timestamp, struct string timestamp_str, char forced, char immediate) { return 0; } @@ -867,6 +933,14 @@ int inspircd3_protocol_handle_oper_user(struct string from, struct user_info *in return 0; } +int inspircd3_protocol_handle_set_account(struct string from, struct user_info *user, struct string account, struct string source) { + return 0; +} + +int inspircd3_protocol_handle_set_cert(struct string from, struct user_info *user, struct string cert, struct string source) { + return 0; +} + int inspircd3_protocol_handle_set_channel(struct string from, struct channel_info *channel, char is_new_channel, size_t user_count, struct user_info **users) { return 0; } @@ -907,7 +981,7 @@ void inspircd3_protocol_fail_new_user(struct string from, struct user_info *info return; } -void inspircd3_protocol_fail_rename_user(struct string from, struct user_info *info, struct string nick, size_t timestamp, struct string timestamp_str) { +void inspircd3_protocol_fail_rename_user(struct string from, struct user_info *info, struct string nick, size_t timestamp, struct string timestamp_str, char forced, char immediate) { return; } @@ -915,6 +989,14 @@ void inspircd3_protocol_fail_oper_user(struct string from, struct user_info *inf return; } +void inspircd3_protocol_fail_set_account(struct string from, struct user_info *user, struct string account, struct string source) { + return; +} + +void inspircd3_protocol_fail_set_cert(struct string from, struct user_info *user, struct string cert, struct string source) { + return; +} + void inspircd3_protocol_fail_set_channel(struct string from, struct channel_info *channel, char is_new_channel, size_t user_count, struct user_info **users) { return; } @@ -991,6 +1073,21 @@ void inspircd3_protocol_introduce_servers_to(size_t net, void *handle) { inspircd3_protocol_introduce_servers_to_inner(net, handle, SID, info); } } + + for (size_t i = 0; i < server_list.len; i++) { + struct server_info *target = server_list.array[i].ptr; + if (target != self && target->protocol != INSPIRCD3_PROTOCOL) { + networks[net].send(handle, STRING(":")); + networks[net].send(handle, SID); + networks[net].send(handle, STRING(" SERVER ")); + networks[net].send(handle, target->name); + networks[net].send(handle, STRING(" * 0 ")); + networks[net].send(handle, target->sid); + networks[net].send(handle, STRING(" :")); + networks[net].send(handle, target->fullname); + networks[net].send(handle, STRING("\n")); + } + } } void inspircd3_protocol_introduce_user_to(size_t net, void *handle, struct user_info *user, char join_channels) { @@ -1391,7 +1488,7 @@ int inspircd3_protocol_handle_nick(struct string source, size_t argc, struct str if (!user) return 0; // KILL timings, etc - if (rename_user(config->sid, user, argv[0], nick_ts) != 0) + if (rename_user(config->sid, user, argv[0], nick_ts, 0, 1) != 0) return -1; return 0; @@ -1538,7 +1635,7 @@ int inspircd3_protocol_handle_fjoin(struct string source, size_t argc, struct st i++; - while (i < argv[arg_i].len && argv[arg_i].data[i] != ':') + while (i < argv[arg_i].len && argv[arg_i].data[i] != ':' && argv[arg_i].data[i] != ' ') i++; user_count++; @@ -1569,7 +1666,7 @@ int inspircd3_protocol_handle_fjoin(struct string source, size_t argc, struct st uid.data = &(argv[arg_i].data[i]); - while (i < argv[arg_i].len && argv[arg_i].data[i] != ':') + while (i < argv[arg_i].len && argv[arg_i].data[i] != ':' && argv[arg_i].data[i] != ' ') i++; uid.len = (size_t)(&(argv[arg_i].data[i]) - uid.data); @@ -1589,6 +1686,8 @@ int inspircd3_protocol_handle_fjoin(struct string source, size_t argc, struct st i++; mid.len = (size_t)(&(argv[arg_i].data[i]) - mid.data); + if (mid.len == 0) + mid = STRING("0"); char err; size_t mid_number = str_to_unsigned(mid, &err); @@ -1657,97 +1756,360 @@ int inspircd3_protocol_handle_fjoin(struct string source, size_t argc, struct st return -1; } -//// :source PART <channel> [<reason>] -//int inspircd3_protocol_handle_part(struct string source, size_t argc, struct string *argv, size_t net, void *handle, struct server_config *config, char is_incoming) { -// if (argc < 1) { -// WRITES(2, STRING("[InspIRCd v3] Invalid PART received! (Missing parameters)\r\n")); -// return -1; -// } -// struct string reason; -// if (argc < 2) -// reason = STRING(""); -// else -// reason = argv[1]; -// -// struct user_info *user = get_table_index(user_list, source); -// if (!user) -// return 0; -// -// struct channel_info *channel = get_table_index(channel_list, argv[0]); -// if (!channel) -// return 0; -// -// part_channel(config->sid, channel, user, reason, 1); -// -// return 0; -//} -// -//// [:source] KICK <channel> <user> [<reason>] -//int inspircd3_protocol_handle_kick(struct string source, size_t argc, struct string *argv, size_t net, void *handle, struct server_config *config, char is_incoming) { -// if (argc < 2) { -// WRITES(2, STRING("[InspIRCd v3] Invalid KICK received! (Missing parameters)\r\n")); -// return -1; -// } -// -// struct channel_info *channel = get_table_index(channel_list, argv[0]); -// if (!channel) -// return 0; -// -// struct user_info *user = get_table_index(user_list, argv[1]); -// if (!user) { -// char found = 0; -// for (size_t i = 0; i < user_list.len; i++) { -// user = user_list.array[i].ptr; -// if (STRING_EQ(user->nick, argv[1])) { -// found = 1; -// break; -// } -// } -// if (!found) -// return 0; -// } -// -// int rejoin; -// if (argc > 2) -// rejoin = kick_channel(config->sid, source, channel, user, argv[2]); -// else -// rejoin = kick_channel(config->sid, source, channel, user, STRING("")); -// -// if (rejoin) { -// networks[net].send(handle, STRING(":")); -// networks[net].send(handle, SID); -// networks[net].send(handle, STRING(" FJOIN ")); -// networks[net].send(handle, channel->name); -// networks[net].send(handle, STRING(" ")); -// networks[net].send(handle, channel->channel_ts_str); -// networks[net].send(handle, STRING(" + :,")); -// networks[net].send(handle, user->uid); -// networks[net].send(handle, STRING("\n")); -// } -// -// return 0; -//} -// -//// [:source] PRIVMSG <target> <message> -//int inspircd3_protocol_handle_privmsg(struct string source, size_t argc, struct string *argv, size_t net, void *handle, struct server_config *config, char is_incoming) { -// if (argc < 2) { -// WRITES(2, STRING("[InspIRCd v3] Invalid PRIVMSG received! (Missing parameters)\r\n")); -// return -1; -// } -// -// privmsg(config->sid, source, argv[0], argv[1]); -// -// return 0; -//} -// -//// [:source] NOTICE <target> <message> -//int inspircd3_protocol_handle_notice(struct string source, size_t argc, struct string *argv, size_t net, void *handle, struct server_config *config, char is_incoming) { -// if (argc < 2) { -// WRITES(2, STRING("[InspIRCd v3] Invalid NOTICE received! (Missing parameters)\r\n")); -// return -1; -// } -// -// notice(config->sid, source, argv[0], argv[1]); -// -// return 0; -//} +// :source IJOIN <channel> <member id> +int inspircd3_protocol_handle_ijoin(struct string source, size_t argc, struct string *argv, size_t net, void *handle, struct server_config *config, char is_incoming) { + if (argc < 2) { + WRITES(2, STRING("[InspIRCd v3] Invalid IJOIN received! (Missing parameters)\r\n")); + return -1; + } + + struct user_info *user = get_table_index(user_list, source); + if (!user) + return 0; + + struct string *mid; + mid = malloc(sizeof(*mid)); + if (!mid) + return -1; + + if (str_clone(mid, argv[1]) != 0) { + free(mid); + return -1; + } + + struct inspircd3_protocol_specific_user *this = user->protocol_specific[INSPIRCD3_PROTOCOL]; + + struct string *old_mid = get_table_index(this->memberships, argv[0]); + if (set_table_index(&(this->memberships), argv[0], mid) != 0) { + free(mid->data); + free(mid); + return -1; + } + + struct channel_info *channel = get_table_index(channel_list, argv[0]); + if (!channel) { + size_t timestamp; + { + ssize_t t = time(0); + if (t < 0) { + WRITES(2, STRING("Please check your clock.\r\n")); + if (old_mid) + set_table_index(&(this->memberships), argv[0], old_mid); + else + remove_table_index(&(this->memberships), argv[0]); + free(mid->data); + free(mid); + return -1; + } + timestamp = (size_t)t; + } + if (set_channel(config->sid, argv[0], timestamp, 1, &user) != 0) { + if (old_mid) + set_table_index(&(this->memberships), argv[0], old_mid); + else + remove_table_index(&(this->memberships), argv[0]); + free(mid->data); + free(mid); + return -1; + } + } else { + if (join_channel(config->sid, channel, 1, &user, 1) != 0) { + if (old_mid) + set_table_index(&(this->memberships), argv[0], old_mid); + else + remove_table_index(&(this->memberships), argv[0]); + free(mid->data); + free(mid); + return -1; + } + } + + if (old_mid) { + free(old_mid->data); + free(old_mid); + } + + return 0; +} + +// :source PART <channel> [<reason>] +int inspircd3_protocol_handle_part(struct string source, size_t argc, struct string *argv, size_t net, void *handle, struct server_config *config, char is_incoming) { + if (argc < 1) { + WRITES(2, STRING("[InspIRCd v3] Invalid PART received! (Missing parameters)\r\n")); + return -1; + } + struct string reason; + if (argc < 2) + reason = STRING(""); + else + reason = argv[1]; + + struct user_info *user = get_table_index(user_list, source); + if (!user) + return 0; + + struct channel_info *channel = get_table_index(channel_list, argv[0]); + if (!channel) + return 0; + + part_channel(config->sid, channel, user, reason, 1); + + return 0; +} + +// [:source] KICK <channel> <user> [<reason>] +int inspircd3_protocol_handle_kick(struct string source, size_t argc, struct string *argv, size_t net, void *handle, struct server_config *config, char is_incoming) { + if (argc < 2) { + WRITES(2, STRING("[InspIRCd v3] Invalid KICK received! (Missing parameters)\r\n")); + return -1; + } + + struct channel_info *channel = get_table_index(channel_list, argv[0]); + if (!channel) + return 0; + + struct user_info *user = get_table_index(user_list, argv[1]); + if (!user) { + char found = 0; + for (size_t i = 0; i < user_list.len; i++) { + user = user_list.array[i].ptr; + if (STRING_EQ(user->nick, argv[1])) { + found = 1; + break; + } + } + if (!found) + return 0; + } + + int rejoin; + if (argc > 2) + rejoin = kick_channel(config->sid, source, channel, user, argv[2]); + else + rejoin = kick_channel(config->sid, source, channel, user, STRING("")); + + if (rejoin) { + struct server_info *server = get_table_index(server_list, user->server); + networks[net].send(handle, STRING(":")); + networks[net].send(handle, SID); + networks[net].send(handle, STRING(" FJOIN ")); + networks[net].send(handle, channel->name); + networks[net].send(handle, STRING(" ")); + networks[net].send(handle, channel->channel_ts_str); + networks[net].send(handle, STRING(" + :,")); + networks[net].send(handle, user->uid); + if (!STRING_EQ(server->sid, SID) && server->protocol == INSPIRCD3_PROTOCOL) { + networks[net].send(handle, STRING(":")); + struct inspircd3_protocol_specific_user *prot_specific = user->protocol_specific[INSPIRCD3_PROTOCOL]; + struct string *mid = get_table_index(prot_specific->memberships, channel->name); + if (mid) + networks[net].send(handle, *mid); + else + networks[net].send(handle, STRING("0")); + networks[net].send(handle, STRING("\n")); + } else { + networks[net].send(handle, STRING(":0\n")); + } + } + + return 0; +} + +// [:source] PRIVMSG <target> <message> +int inspircd3_protocol_handle_privmsg(struct string source, size_t argc, struct string *argv, size_t net, void *handle, struct server_config *config, char is_incoming) { + if (argc < 2) { + WRITES(2, STRING("[InspIRCd v3] Invalid PRIVMSG received! (Missing parameters)\r\n")); + return -1; + } + + privmsg(config->sid, source, argv[0], argv[1]); + + return 0; +} + +// [:source] NOTICE <target> <message> +int inspircd3_protocol_handle_notice(struct string source, size_t argc, struct string *argv, size_t net, void *handle, struct server_config *config, char is_incoming) { + if (argc < 2) { + WRITES(2, STRING("[InspIRCd v3] Invalid NOTICE received! (Missing parameters)\r\n")); + return -1; + } + + notice(config->sid, source, argv[0], argv[1]); + + return 0; +} + +// :source MODE <target> <modes> [<mode args>] +int inspircd3_protocol_handle_mode(struct string source, size_t argc, struct string *argv, size_t net, void *handle, struct server_config *config, char is_incoming) { + if (argc < 2) { + WRITES(2, STRING("[InspIRCd v3] Invalid MODE received! (Missing parameters)\r\n")); + return -1; + } + + struct user_info *user = get_table_index(user_list, argv[0]); + if (!user) { + if (has_table_index(server_list, argv[0])) + return 0; // TODO: Probably not actually valid + + char found = 0; + for (size_t i = 0; i < user_list.len; i++) { + user = user_list.array[i].ptr; + if (case_string_eq(user->nick, argv[0])) { + found = 1; + break; + } + } + + if (!found) + return 0; + } + + if (user) { + size_t arg_i = 2; + char dir = '?'; + for (size_t i = 0; i < argv[1].len; i++) { + switch(argv[1].data[i]) { + case '+': + case '-': + dir = argv[1].data[i]; + break; + default: + if (dir == '?') { + WRITES(2, STRING("[InspIRCd v3] Invalid MODE received (Mode direction not set)\r\n")); + return -1; + } + switch(inspircd3_protocol_user_mode_types[(unsigned char)argv[1].data[i]]) { + case MODE_TYPE_NOARGS: + if (dir == '-' && argv[1].data[i] == 'o') { + if (oper_user(config->sid, user, STRING(""), source) != 0) + return -1; + } + break; + case MODE_TYPE_REPLACE: + case MODE_TYPE_MODE: + if (dir == '-') + break; + case MODE_TYPE_MULTIPLE: + arg_i++; + break; + case MODE_TYPE_USERS: + arg_i++; + break; + default: + WRITES(2, STRING("[InspIRCd v3] Invalid MODE received! (Unknown mode given)\r\n")); + return -1; + } + } + } + } + + return 0; +} + +// :source FMODE <target> <timestamp> <modes> [<mode args>] +int inspircd3_protocol_handle_fmode(struct string source, size_t argc, struct string *argv, size_t net, void *handle, struct server_config *config, char is_incoming) { + if (argc < 3) { + WRITES(2, STRING("[InspIRCd v3] Invalid MODE received! (Missing parameters)\r\n")); + return -1; + } + + struct user_info *user = get_table_index(user_list, argv[0]); + if (!user) { + if (has_table_index(server_list, argv[0])) + return 0; // TODO: Probably not actually valid + + char found = 0; + for (size_t i = 0; i < user_list.len; i++) { + user = user_list.array[i].ptr; + if (case_string_eq(user->nick, argv[0])) { + found = 1; + break; + } + } + + if (!found) + return 0; + } + + if (user) { + size_t arg_i = 3; + char dir = '?'; + for (size_t i = 0; i < argv[2].len; i++) { + switch(argv[2].data[i]) { + case '+': + case '-': + dir = argv[2].data[i]; + break; + default: + if (dir == '?') { + WRITES(2, STRING("[InspIRCd v3] Invalid MODE received (Mode direction not set)\r\n")); + return -1; + } + switch(inspircd3_protocol_user_mode_types[(unsigned char)argv[2].data[i]]) { + case MODE_TYPE_NOARGS: + if (dir == '-' && argv[2].data[i] == 'o') { + if (oper_user(config->sid, user, STRING(""), source) != 0) + return -1; + } + break; + case MODE_TYPE_REPLACE: + case MODE_TYPE_MODE: + if (dir == '-') + break; + case MODE_TYPE_MULTIPLE: + arg_i++; + break; + case MODE_TYPE_USERS: + arg_i++; + break; + default: + WRITES(2, STRING("[InspIRCd v3] Invalid MODE received! (Unknown mode given)\r\n")); + return -1; + } + } + } + } + + return 0; +} + +// [:source] METADATA <target> <key> <value> +int inspircd3_protocol_handle_metadata(struct string source, size_t argc, struct string *argv, size_t net, void *handle, struct server_config *config, char is_incoming) { + if (argc < 3) { + WRITES(2, STRING("[InspIRCd v3] Invalid METADATA received! (Missing parameters)\r\n")); + return -1; + } + + struct user_info *info; + do { + info = get_table_index(user_list, argv[0]); + if (info) + break; + + return 0; + } while (0); + + if (STRING_EQ(argv[1], STRING("accountname"))) { + if (set_account(config->sid, info, argv[2], source) != 0) + return -1; + } else if (STRING_EQ(argv[1], STRING("ssl_cert"))) { + struct string no_cert = STRING("vtrsE "); + if (argv[2].len < no_cert.len) + return -1; + struct string start = {.data = argv[2].data, .len = no_cert.len}; + if (STRING_EQ(start, no_cert)) { + if (set_cert(config->sid, info, STRING(""), source) != 0) + return -1; + } else if (STRING_EQ(start, STRING("vTrse "))) { + struct string cert = {.data = argv[2].data + no_cert.len, .len = argv[2].len - no_cert.len}; + size_t len; + for (len = 0; len < cert.len && cert.data[len] != ' '; len++) + ; + cert.len = len; + if (set_cert(config->sid, info, cert, source) != 0) + return -1; + } + } + + return 0; +} diff --git a/protocols/inspircd3.h b/protocols/inspircd3.h index 69e962d..1f3dba4 100644 --- a/protocols/inspircd3.h +++ b/protocols/inspircd3.h @@ -60,12 +60,13 @@ void inspircd3_protocol_propagate_new_server(struct string from, struct string a void inspircd3_protocol_propagate_unlink_server(struct string from, struct server_info *a, struct server_info *b, size_t protocol); void inspircd3_protocol_propagate_new_user(struct string from, struct user_info *info); -void inspircd3_protocol_propagate_rename_user(struct string from, struct user_info *info, struct string nick, size_t timestamp, struct string timestamp_str); +void inspircd3_protocol_propagate_rename_user(struct string from, struct user_info *info, struct string nick, size_t timestamp, struct string timestamp_str, char forced, char immediate); void inspircd3_protocol_propagate_remove_user(struct string from, struct user_info *info, struct string reason); void inspircd3_protocol_propagate_kill_user(struct string from, struct string source, struct user_info *info, struct string reason); -void inspircd3_protocol_propagate_oper_user(struct string from, struct user_info *info, struct string type, struct string source); +void inspircd3_protocol_propagate_oper_user(struct string from, struct user_info *user, struct string type, struct string source); -void inspircd3_protocol_propagate_set_account(struct string from, struct user_info *info, struct string account); +void inspircd3_protocol_propagate_set_account(struct string from, struct user_info *user, struct string account, struct string source); +void inspircd3_protocol_propagate_set_cert(struct string from, struct user_info *user, struct string cert, struct string source); void inspircd3_protocol_propagate_set_channel(struct string from, struct channel_info *channel, char is_new_channel, size_t user_count, struct user_info **users); void inspircd3_protocol_propagate_join_channel(struct string from, struct channel_info *channel, size_t user_count, struct user_info **users); @@ -79,12 +80,13 @@ int inspircd3_protocol_handle_new_server(struct string from, struct string attac void inspircd3_protocol_handle_unlink_server(struct string from, struct server_info *a, struct server_info *b, size_t protocol); int inspircd3_protocol_handle_new_user(struct string from, struct user_info *info); -int inspircd3_protocol_handle_rename_user(struct string from, struct user_info *info, struct string nick, size_t timestamp, struct string timestamp_str); +int inspircd3_protocol_handle_rename_user(struct string from, struct user_info *info, struct string nick, size_t timestamp, struct string timestamp_str, char forced, char immediate); void inspircd3_protocol_handle_remove_user(struct string from, struct user_info *info, struct string reason, char propagate); void inspircd3_protocol_handle_kill_user(struct string from, struct string source, struct user_info *info, struct string reason); int inspircd3_protocol_handle_oper_user(struct string from, struct user_info *info, struct string type, struct string source); -int inspircd3_protocol_handle_set_account(struct string from, struct user_info *info, struct string account); +int inspircd3_protocol_handle_set_account(struct string from, struct user_info *user, struct string account, struct string source); +int inspircd3_protocol_handle_set_cert(struct string from, struct user_info *user, struct string cert, struct string source); int inspircd3_protocol_handle_set_channel(struct string from, struct channel_info *channel, char is_new_channel, size_t user_count, struct user_info **users); int inspircd3_protocol_handle_join_channel(struct string from, struct channel_info *channel, size_t user_count, struct user_info **users, char propagate); @@ -94,10 +96,11 @@ void inspircd3_protocol_handle_kick_channel(struct string from, struct string so void inspircd3_protocol_fail_new_server(struct string from, struct string attached_to, struct server_info *info); void inspircd3_protocol_fail_new_user(struct string from, struct user_info *info); -void inspircd3_protocol_fail_rename_user(struct string from, struct user_info *info, struct string nick, size_t timestamp, struct string timestamp_str); +void inspircd3_protocol_fail_rename_user(struct string from, struct user_info *info, struct string nick, size_t timestamp, struct string timestamp_str, char forced, char immediate); void inspircd3_protocol_fail_oper_user(struct string from, struct user_info *info, struct string type, struct string source); -void inspircd3_protocol_fail_set_account(struct string from, struct user_info *info, struct string account); +void inspircd3_protocol_fail_set_account(struct string from, struct user_info *user, struct string account, struct string source); +void inspircd3_protocol_fail_set_cert(struct string from, struct user_info *user, struct string cert, struct string source); void inspircd3_protocol_fail_set_channel(struct string from, struct channel_info *channel, char is_new_channel, size_t user_count, struct user_info **users); void inspircd3_protocol_fail_join_channel(struct string from, struct channel_info *channel, size_t user_count, struct user_info **users, char propagate); @@ -125,13 +128,17 @@ int inspircd3_protocol_handle_kill(struct string source, size_t argc, struct str int inspircd3_protocol_handle_opertype(struct string source, size_t argc, struct string *argv, size_t net, void *handle, struct server_config *config, char is_incoming); int inspircd3_protocol_handle_fjoin(struct string source, size_t argc, struct string *argv, size_t net, void *handle, struct server_config *config, char is_incoming); +int inspircd3_protocol_handle_ijoin(struct string source, size_t argc, struct string *argv, size_t net, void *handle, struct server_config *config, char is_incoming); int inspircd3_protocol_handle_part(struct string source, size_t argc, struct string *argv, size_t net, void *handle, struct server_config *config, char is_incoming); int inspircd3_protocol_handle_kick(struct string source, size_t argc, struct string *argv, size_t net, void *handle, struct server_config *config, char is_incoming); int inspircd3_protocol_handle_privmsg(struct string source, size_t argc, struct string *argv, size_t net, void *handle, struct server_config *config, char is_incoming); int inspircd3_protocol_handle_notice(struct string source, size_t argc, struct string *argv, size_t net, void *handle, struct server_config *config, char is_incoming); -int inspircd3_protocol_handle_dump(struct string source, size_t argc, struct string *argv, size_t net, void *handle, struct server_config *config, char is_incoming); +int inspircd3_protocol_handle_mode(struct string source, size_t argc, struct string *argv, size_t net, void *handle, struct server_config *config, char is_incoming); +int inspircd3_protocol_handle_fmode(struct string source, size_t argc, struct string *argv, size_t net, void *handle, struct server_config *config, char is_incoming); + +int inspircd3_protocol_handle_metadata(struct string source, size_t argc, struct string *argv, size_t net, void *handle, struct server_config *config, char is_incoming); extern char inspircd3_protocol_user_mode_types[UCHAR_MAX+1]; extern char inspircd3_protocol_channel_mode_types[UCHAR_MAX+1]; |