static boolean process_request(SSL *ssl_client) { char buffer[BUFFER_LENGTH + 1]; char token_name[TOKEN_NAME_LENGTH + 1]; char request[REQUEST_TYPE_LENGTH + 1]; // Receive request information if(SSL_recv_buffer(ssl_client, buffer, NULL) == 0) { fprintf(stderr, "Receiving request information failed\n"); goto ERROR; } // Get a request information token from buffer if(read_token_from_buffer(buffer, 1, token_name, request) != READ_TOKEN_SUCCESS || strcmp(token_name, "request") != 0) int_error("Extracting the request failed"); if(strcmp(request, USER_REGISTRATION) == 0) { return register_user(ssl_client, false); } else if(strcmp(request, USER_EMAIL_ADDRESS_EDITING) == 0) { return edit_user_email_address(ssl_client, false); } else if(strcmp(request, USER_PASSWD_RESETTING) == 0) { return reset_user_passwd(ssl_client, false); } else if(strcmp(request, USER_REMOVAL) == 0) { return remove_user(ssl_client, false); } else if(strcmp(request, ADMIN_REGISTRATION) == 0) { return register_user(ssl_client, true); } else if(strcmp(request, ADMIN_EMAIL_ADDRESS_EDITING) == 0) { return edit_user_email_address(ssl_client, true); } else if(strcmp(request, ADMIN_PASSWD_RESETTING) == 0) { return reset_user_passwd(ssl_client, true); } else if(strcmp(request, ADMIN_REMOVAL) == 0) { return remove_user(ssl_client, true); } else { fprintf(stderr, "Invalid request type\n"); goto ERROR; } ERROR: return false; }
/* * mr_pong - registration message handler * * parv[0] = sender prefix * parv[1] = pong response echo * NOTE: cptr is always unregistered here */ int mr_pong(struct Client* cptr, struct Client* sptr, int parc, char* parv[]) { assert(0 != cptr); assert(cptr == sptr); assert(!IsRegistered(sptr)); ClrFlag(cptr, FLAG_PINGSENT); cli_lasttime(cptr) = CurrentTime; /* * Check to see if this is a PONG :cookie reply from an * unregistered user. If so, process it. -record */ if (0 != cli_cookie(sptr) && COOKIE_VERIFIED != cli_cookie(sptr)) { if (parc > 1 && cli_cookie(sptr) == atol(parv[parc - 1])) { cli_cookie(sptr) = COOKIE_VERIFIED; if (cli_user(sptr) && *(cli_user(sptr))->host && (cli_name(sptr))[0]) /* * NICK and USER OK */ return register_user(cptr, sptr, cli_name(sptr), cli_user(sptr)->username); } else send_reply(sptr, SND_EXPLICIT | ERR_BADPING, ":To connect, type /QUOTE PONG %u", cli_cookie(sptr)); } return 0; }
void showMenu(){ char ch; while(1){ system("clear"); printf("##########################################\n"); printf("## 个人用户端 ##\n"); printf("##########################################\n"); printf("## 1.用户注册 ##\n"); printf("## ##\n"); printf("## 2.用户登录 ##\n"); printf("## ##\n"); printf("## 3.退出程序 ##\n"); printf("##########################################\n"); while((ch=getchar())!='\n'); printf("请输入选择:"); ch = getchar(); switch(ch){ case '1': register_user(); break; case '2': login(); break; case '3': close(sfd); exit(0); break; default: break; } } }
/*解析消息线程*/ void *pthread_func() { head_user = (struct user_info *)malloc(sizeof(struct user_info)); head_user->next = NULL; struct user_info *tmp; // 循环变量,用于便利在线用户链表将其发送给第一次登录的或者有刷新请求的客户端 struct servmsg *free_tmp; int ret= -1; while(1) { while(H->next != NULL) { // free_tmp = H; H = H->next; //消息头,处理玩就往后移动 // free(free_tmp);//将处理完的消息所占内存释放掉 // free_tmp = NULL; printf("消息链表首地址H :%p\n",H); printf("准备解析消息---\n"); printf("消息来自%s:\tIP:%s(%d)\n",H->recvmsg.self_name,inet_ntoa(H->addr.sin_addr),ntohs(H->addr.sin_port)); if(H->recvmsg.type == REGISTER) { register_user(); continue; } if(H->recvmsg.type == LOG_IN ) { check_user(); // if(find) { add_user(head_user,H);// add } continue; } if(H->recvmsg.type == REFRESH){ printf("%s刷新消息\n",H->recvmsg.self_name); //usleep(50000); send_all_online(H->addr); continue; } if (H->recvmsg.type == OFFLINE){ printf("%s下线\n",H->recvmsg.self_name); delete_user(H->recvmsg.self_name); } if (H->recvmsg.type == CHAT_PRI){ printf("%s私聊消息\n",H->recvmsg.self_name); printf("目标:%s\n",H->recvmsg.dst_name); chat_private(); } if(H->recvmsg.type == CHAT_ALL){ printf("%s群聊消息\n",H->recvmsg.self_name); chat_toall(); } printf("-----------------------------------\n"); }//end while(H) } }
static void register_with_outbound(const char *transport, int use_transaction,const char* outbound ) { belle_sip_request_t *req; req=register_user(stack, prov, transport,use_transaction,"tester",outbound); if (req) { unregister_user(stack,prov,req,use_transaction); belle_sip_object_unref(req); } }
int application_request(int fd,data_person * users,int * newid) { binary_semaphore_wait(semaphore); person person; simple_person * simple_person; int ans=0; clsvbuff buff; if(read_msg(fd,&buff)<0) return -1; switch(buff.opc) { case GET_INFO: ans = get_info(&buff,users,newid,&person); ans_get_info(fd,&buff,ans,&person); break; case GET_MATCHS: ans = get_matchs(&buff,users,&simple_person); ans_get_matchs(fd,ans,&buff,&simple_person); break; case SHOW_PEOPLE: ans = show_people(&buff,users,newid,&simple_person); ans_show_people(fd,ans,&buff,&simple_person); break; case REGISTER: ans=register_user(&buff,users,newid); ans_register_user(fd,ans,&buff); break; case LOGIN: /*In this case ans doubles as opOK*/ ans = login(&buff,users,newid); ans_login(fd,ans,&buff); break; case EVALUATION: /*In this case ans doubles as opOK*/ users[buff.id_client-1].last_evaluation=buff.data.clsv_evaluation.id; if(buff.data.clsv_evaluation.like==true) { ans = evaluation(&buff,users); ans_evaluation(fd,ans,&buff); } else ans_evaluation(fd,0,&buff); break; default: /*OPC NOT RECOGNIZED*/ return -1; break; } binary_semaphore_post(semaphore); return 0; }
static void register_u(Request * request) { bool result = register_user(request->params[0], request->params[1]); ResponseStatus rs; if (result) { strcpy(username, request->params[0]); rs = SUCCESS; state = VERIFIED; } else { rs = FAILED; } send_response(rs, 0, NULL); }
int main(object me, string arg) { string id, email; if (!arg || sscanf(arg, "%s %s", id, email) != 2) { return notify_fail("指令格式:register <id> <email>\n"); } switch(register_user(me->query("id"), id, email)) { case 0: return notify_fail("登记失败。\n"); break; default: return notify_fail(id + " 已经成功地被您登记了。\n"); break; } }
/* ** m_nospoof - allows clients to respond to no spoofing patch ** parv[0] = prefix ** parv[1] = code */ DLLFUNC int m_nospoof(aClient *cptr, aClient *sptr, int parc, char *parv[]) { #ifdef NOSPOOF unsigned long result; #endif Debug((DEBUG_NOTICE, "NOSPOOF")); #ifdef NOSPOOF if (IsNotSpoof(cptr)) return 0; if (IsRegistered(cptr)) return 0; if (!*sptr->name) return 0; if (BadPtr(parv[1])) goto temp; result = strtoul(parv[1], NULL, 16); /* Accept code in second parameter (ircserv) */ if (result != sptr->nospoof) { if (BadPtr(parv[2])) goto temp; result = strtoul(parv[2], NULL, 16); if (result != sptr->nospoof) goto temp; } sptr->nospoof = 0; if (USE_BAN_VERSION && MyConnect(sptr)) sendto_one(sptr, ":IRC!IRC@%s PRIVMSG %s :\1VERSION\1", me.name, sptr->name); if (sptr->user && sptr->name[0]) return register_user(cptr, sptr, sptr->name, sptr->user->username, NULL, NULL, NULL); return 0; temp: /* Homer compatibility */ sendto_one(cptr, ":%X!nospoof@%s PRIVMSG %s :\1VERSION\1", cptr->nospoof, me.name, cptr->name); #endif return 0; }
// Return 1 on success, 0 on failure int add_achievement_progress(int achievement_id, int add_progress_count){ if(achievement_system_disabled){ return ACHIEVEMENT_PUSH_FAILURE; } if(ACHIEVEMENT_DEBUG){pline("DEBUG: add_achievement_progress(%i, %i)", achievement_id, add_progress_count);} if(check_db_connection()){ disable_achievements(); } //Check if user exists if(!user_exists()){ register_user(); } //Calculate user's completion on this achievement int pre_achievement_progress = get_achievement_progress(achievement_id); int max_achievement_progress = get_achievement_max_progress(achievement_id); if(ACHIEVEMENT_DEBUG){pline("DEBUG: get_achievement_max_progress(%i)=%i", achievement_id, max_achievement_progress);} if(pre_achievement_progress < max_achievement_progress){ //user still needs achievement if(pre_achievement_progress + add_progress_count >= max_achievement_progress){ //Achievement fully achieved! if(push_achievement_progress(achievement_id, max_achievement_progress)){ //floor the value to max_progress char * achievement_name = get_achievement_name(achievement_id); pline("Congratulations! You've earned the achievement: %s", achievement_name); free(achievement_name); return ACHIEVEMENT_PUSH_SUCCESS; } else{ pline("Er, oops. You got an achievement, but it can't be recorded."); return ACHIEVEMENT_PUSH_FAILURE; } } else{ //user stills needs achievement, but isn't quite there yet if(push_achievement_progress(achievement_id, pre_achievement_progress+add_progress_count)){ return ACHIEVEMENT_PUSH_SUCCESS; } else{ return ACHIEVEMENT_PUSH_FAILURE; } } } return ACHIEVEMENT_PUSH_SUCCESS; }
int main(void) { int listenfd = 0,connfd = 0, n=0; struct sockaddr_in serv_addr; struct sockaddr_in peer; logged_in = 0; char check[1024]; char sendbuff[1024]; char buffer[1024]; char str1[1024], str2[1024]; int numrv,size, result; int max_size = 1024; int closed = 0; int peer_len = sizeof(peer); pid_t pid; strcpy(str2,"Welcome to Online File Sharing service.\nPlease follow the instruction\n\n"); listenfd = socket(AF_INET, SOCK_STREAM, 0); printf("SERVER successfully launched\n\n"); memset(&serv_addr, '0', sizeof(serv_addr)); memset(buffer, '0', sizeof(buffer)); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); serv_addr.sin_port = htons(5000); bind(listenfd, (struct sockaddr*)&serv_addr,sizeof(serv_addr)); if(listen(listenfd, 10) == -1){ printf("Failed to listen\n"); return -1; } while(1) { if(closed == 1) break; connfd = accept(listenfd, (struct sockaddr*)NULL ,NULL); // accept awaiting request if ( (pid = fork()) == 0 ) { close(listenfd); sendbuff[0] = '\0'; strcpy(sendbuff,"Connected with server\n"); size = max_size; sendbuff[22] = '\0'; if((n=send_mssg(connfd,sendbuff,size))==-1) { close(connfd); break; } if((n=recv_mssg(connfd, buffer, size))==-1) exit(1); else if(n==0) break; query_check(buffer, ip, 1); query_check(buffer, port, 2); printf("%s: %s", ip, port); while(1){ if(logged_in == 0) { strcpy(str1,"1. New Client: Register (Syntax: \"register <username> <password>\")\n2. Existing Client: Login (Syntax: \"login <username> <password>\")\n3. For closing connection(Syntax: \"close\")\n\n"); sendbuff[0] = '\0'; strcat(sendbuff,str2); strcat(sendbuff,str1); size = max_size; sendbuff[strlen(str1)+strlen(str2)-1] = '\0'; if((n=send_mssg(connfd,sendbuff,size))==-1) { close(connfd); break; } if((n=recv_mssg(connfd, buffer, size))==-1) exit(1); else if(n==0) break; if(query_check(buffer, check, 1)<0) strcpy(str2,"No such query\n\n"); else { if(strcmp(check,"register")==0) { result = register_user(buffer); if(result == 1) { strcpy(str2, "Successfully Registered\n\n"); } else { strcpy(str2, "Unable to Register. Please try again\n\n"); } } else if(strcmp(check,"login")==0) { result = login_user(buffer,connfd); if(result == 1) { strcpy(str2, "Successfully Logged in\n\n"); } else { strcpy(str2, "Unable to Login. Please try again or register\n\n"); } } else if(strcmp(check,"close")==0) { close(connfd); closed = 1; break; } else strcpy(str2, "No such query\n\n"); } } else { strcpy(str1,"1. Share File (Syntax: \"share <filename> <filepath>\")\n2. Search a file(Syntax: \"search <filename>\")\n3. Logout from server (Syntax: \"logout\")\n\n"); sendbuff[0] = '\0'; strcat(sendbuff,str2); strcat(sendbuff,str1); size = max_size; sendbuff[strlen(str1)+strlen(str2)-1] = '\0'; if((n=send_mssg(connfd,sendbuff,size))==-1) { close(connfd); break; } if((n=recv_mssg(connfd, buffer, size))==-1) exit(1); else if(n==0) break; if(query_check(buffer, check, 1)<0) strcpy(str2,"No such query\n\n"); else { if(strcmp(check,"share")==0) { result = share_file(buffer); if(result == 1) { strcpy(str2, "File successfully shared\n\n"); } else { strcpy(str2, "Unable to share the file. Please try again\n\n"); } } else if(strcmp(check,"search")==0) { char final_list[1024]; final_list[0] = '\0'; result = search_file(buffer, final_list); if(result == 1) { str2[0]='\0'; strcat(str2, "Search complete: RESULT: \n\n"); if(final_list[0]=='\0') strcat(str2, "No match Found\n\n"); else strcat(str2, final_list); } else { strcpy(str2, "Search failed\n\n"); } } else if(strcmp(check,"logout")==0) { log_out(); logged_in = 0; str2[0]='\0'; } else strcpy(str2, "No such query\n"); } } } log_out(); close(connfd); exit(0); } close(connfd); } return 0; }
/* * m_nick * parv[0] = sender prefix * parv[1] = nickname * parv[2] = hopcount when new user; TS when nick change * parv[3] = TS * ---- new user only below ---- * parv[4] = umode * parv[5] = username * parv[6] = hostname * parv[7] = server * parv[8] = serviceid * parv[9] = IP * parv[10] = ircname * -- endif */ int m_nick(aClient *cptr, aClient *sptr, int parc, char *parv[]) { struct simBan *ban; aClient *acptr, *uplink; Link *lp, *lp2; char nick[NICKLEN + 2]; ts_val newts = 0; int sameuser = 0, samenick = 0; if (parc < 2) { sendto_one(sptr, err_str(ERR_NONICKNAMEGIVEN), me.name, parv[0]); return 0; } if (!IsServer(sptr) && IsServer(cptr) && parc > 2) newts = atol(parv[2]); else if (IsServer(sptr) && parc > 3) newts = atol(parv[3]); else parc = 2; /* * parc == 2 on a normal client sign on (local) and a normal client * nick change * parc == 4 on a normal server-to-server client nick change * parc == 11 on a normal TS style server-to-server NICK introduction */ if ((IsServer(sptr) || (parc > 4)) && (parc < 11)) { /* * We got the wrong number of params. Someone is trying to trick * us. Kill it. -ThemBones As discussed with ThemBones, not much * point to this code now sending a whack of global kills would * also be more annoying then its worth, just note the problem, * and continue -Dianora */ sendto_realops("IGNORING BAD NICK: %s[%s@%s] on %s (from %s)", parv[1], (parc >= 6) ? parv[5] : "-", (parc >= 7) ? parv[6] : "-", (parc >= 8) ? parv[7] : "-", parv[0]); return 0; } strncpyzt(nick, parv[1], NICKLEN + 1); /* * if do_nick_name() returns a null name OR if the server sent a * nick name and do_nick_name() changed it in some way (due to rules * of nick creation) then reject it. If from a server and we reject * it, and KILL it. -avalon 4/4/92 */ if (do_nick_name(nick) == 0 || (IsServer(cptr) && strcmp(nick, parv[1]))) { sendto_one(sptr, err_str(ERR_ERRONEUSNICKNAME), me.name, parv[0], parv[1], "Erroneous Nickname"); if (IsServer(cptr)) { ircstp->is_kill++; sendto_realops_lev(DEBUG_LEV, "Bad Nick: %s From: %s Via: %s", parv[1], parv[0], get_client_name(cptr, HIDEME)); sendto_one(cptr, ":%s KILL %s :%s (Bad Nick)", me.name, parv[1], me.name); if (sptr != cptr) { /* bad nick change */ sendto_serv_butone(cptr, ":%s KILL %s :%s (Bad Nick)", me.name, parv[0], me.name); sptr->flags |= FLAGS_KILLED; return exit_client(cptr, sptr, &me, "BadNick"); } } return 0; } /* * Check against nick name collisions. * * Put this 'if' here so that the nesting goes nicely on the screen * :) We check against server name list before determining if the * nickname is present in the nicklist (due to the way the below * for loop is constructed). -avalon */ do { if ((acptr = find_server(nick, NULL))) if (MyConnect(sptr)) { sendto_one(sptr, err_str(ERR_NICKNAMEINUSE), me.name, BadPtr(parv[0]) ? "*" : parv[0], nick); return 0; } /* * acptr already has result from find_server * Well. unless we have a capricious server on the net, a nick can * never be the same as a server name - Dianora * That's not the only case; maybe someone broke do_nick_name * or changed it so they could use "." in nicks on their network * - sedition */ if (acptr) { /* * We have a nickname trying to use the same name as a * server. Send out a nick collision KILL to remove the * nickname. As long as only a KILL is sent out, there is no * danger of the server being disconnected. Ultimate way to * jupiter a nick ? >;-). -avalon */ sendto_realops_lev(SKILL_LEV, "Nick collision on %s", sptr->name); ircstp->is_kill++; sendto_one(cptr, ":%s KILL %s :%s (Nick Collision)", me.name, sptr->name, me.name); sptr->flags |= FLAGS_KILLED; return exit_client(cptr, sptr, &me, "Nick/Server collision"); } if (!(acptr = find_client(nick, NULL))) break; /* * If acptr == sptr, then we have a client doing a nick change * between *equivalent* nicknames as far as server is concerned * (user is changing the case of his/her nickname or somesuch) */ if (acptr == sptr) { if (strcmp(acptr->name, nick) == 0) return 0; else break; } /* If user is changing nick to itself no point in propogating */ /* * Note: From this point forward it can be assumed that acptr != * sptr (point to different client structures). * * If the older one is "non-person", the new entry is just * allowed to overwrite it. Just silently drop non-person, and * proceed with the nick. This should take care of the "dormant * nick" way of generating collisions... */ if (IsUnknown(acptr)) { if (MyConnect(acptr)) { exit_client(NULL, acptr, &me, "Overridden"); break; } else if (!(acptr->user)) { sendto_realops_lev(SKILL_LEV, "Nick Collision on %s", parv[1]); sendto_serv_butone(NULL, ":%s KILL %s :%s (Nick Collision)", me.name, acptr->name, me.name); acptr->flags |= FLAGS_KILLED; /* Having no USER struct should be ok... */ return exit_client(cptr, acptr, &me, "Got TS NICK before Non-TS USER"); } } if (!IsServer(cptr)) { /* * NICK is coming from local client connection. Just send * error reply and ignore the command. * parv[0] is empty on connecting clients */ sendto_one(sptr, err_str(ERR_NICKNAMEINUSE), me.name, BadPtr(parv[0]) ? "*" : parv[0], nick); return 0; } /* * NICK was coming from a server connection. Means that the same * nick is registered for different users by different server. * This is either a race condition (two users coming online about * same time, or net reconnecting) or just two net fragments * becoming joined and having same nicks in use. We cannot have * TWO users with same nick--purge this NICK from the system with * a KILL... >;) * * Changed to something reasonable like IsServer(sptr) (true if * "NICK new", false if ":old NICK new") -orabidoo */ if (IsServer(sptr)) { /* * A new NICK being introduced by a neighbouring server (e.g. * message type "NICK new" received) */ if (!newts || !acptr->tsinfo || (newts == acptr->tsinfo)) { sendto_realops_lev(SKILL_LEV, "Nick collision on %s", parv[1]); ircstp->is_kill++; sendto_one(acptr, err_str(ERR_NICKCOLLISION), me.name, acptr->name, acptr->name); sendto_serv_butone(NULL, ":%s KILL %s :%s (Nick Collision)", me.name, acptr->name, me.name); acptr->flags |= FLAGS_KILLED; return exit_client(cptr, acptr, &me, "Nick collision"); } else { /* XXX This looks messed up to me XXX - Raist */ sameuser = (acptr->user) && mycmp(acptr->user->username, parv[5]) == 0 && mycmp(acptr->user->host, parv[6]) == 0; if ((sameuser && newts < acptr->tsinfo) || (!sameuser && newts > acptr->tsinfo)) { return 0; } else { sendto_realops_lev(SKILL_LEV, "Nick collision on %s",parv[1]); ircstp->is_kill++; sendto_one(acptr, err_str(ERR_NICKCOLLISION), me.name, acptr->name, acptr->name); sendto_serv_butone(sptr, ":%s KILL %s :%s (Nick Collision)", me.name, acptr->name, me.name); acptr->flags |= FLAGS_KILLED; (void) exit_client(cptr, acptr, &me, "Nick collision"); break; } } } /* * * A NICK change has collided (e.g. message type * ":old NICK * new". This requires more complex cleanout. * Both clients must be * purged from this server, the "new" * must be killed from the * incoming connection, and "old" must * be purged from all outgoing * connections. */ if (!newts || !acptr->tsinfo || (newts == acptr->tsinfo) || !sptr->user) { sendto_realops_lev(SKILL_LEV, "Nick change collision: %s", parv[1]); ircstp->is_kill++; sendto_one(acptr, err_str(ERR_NICKCOLLISION), me.name, acptr->name, acptr->name); sendto_serv_butone(NULL, ":%s KILL %s :%s (Nick Collision)",me.name, sptr->name, me.name); ircstp->is_kill++; sendto_serv_butone(NULL, ":%s KILL %s :%s (Nick Collision)",me.name, acptr->name, me.name); acptr->flags |= FLAGS_KILLED; (void) exit_client(NULL, acptr, &me, "Nick collision(new)"); sptr->flags |= FLAGS_KILLED; return exit_client(cptr, sptr, &me, "Nick collision(old)"); } else { /* XXX This looks messed up XXX */ sameuser = mycmp(acptr->user->username, sptr->user->username) == 0 && mycmp(acptr->user->host, sptr->user->host) == 0; if ((sameuser && newts < acptr->tsinfo) || (!sameuser && newts > acptr->tsinfo)) { if (sameuser) sendto_realops_lev(SKILL_LEV, "Nick change collision from %s to %s", sptr->name, acptr->name); ircstp->is_kill++; sendto_serv_butone(cptr, ":%s KILL %s :%s (Nick Collision)", me.name, sptr->name, me.name); sptr->flags |= FLAGS_KILLED; if (sameuser) return exit_client(cptr, sptr, &me, "Nick collision(old)"); else return exit_client(cptr, sptr, &me, "Nick collision(new)"); } else { sendto_realops_lev(SKILL_LEV, "Nick collision on %s", acptr->name); ircstp->is_kill++; sendto_one(acptr, err_str(ERR_NICKCOLLISION), me.name, acptr->name, acptr->name); sendto_serv_butone(sptr, ":%s KILL %s :%s (Nick Collision)",me.name, acptr->name, me.name); acptr->flags |= FLAGS_KILLED; (void) exit_client(cptr, acptr, &me, "Nick collision"); } } } while (0); if (IsServer(sptr)) { uplink = find_server(parv[7], NULL); if(!uplink) { /* if we can't find the server this nick is on, * complain loudly and ignore it. - lucas */ sendto_realops("Remote nick %s on UNKNOWN server %s", nick, parv[7]); return 0; } sptr = make_client(cptr, uplink); /* If this is on a U: lined server, it's a U: lined client. */ if(IsULine(uplink)) sptr->flags|=FLAGS_ULINE; add_client_to_list(sptr); if (parc > 2) sptr->hopcount = atoi(parv[2]); if (newts) { sptr->tsinfo = newts; } else { newts = sptr->tsinfo = (ts_val) timeofday; ts_warn("Remote nick %s introduced without a TS", nick); } /* copy the nick in place */ (void) strcpy(sptr->name, nick); (void) add_to_client_hash_table(nick, sptr); if (parc >= 10) { int *s, flag; char *m; /* parse the usermodes -orabidoo */ m = &parv[4][1]; while (*m) { for (s = user_modes; (flag = *s); s += 2) if (*m == *(s + 1)) { if ((flag == UMODE_o) || (flag == UMODE_O)) Count.oper++; sptr->umode |= flag & SEND_UMODES; break; } m++; } if (parc==10) { return do_user(nick, cptr, sptr, parv[5], parv[6], parv[7], strtoul(parv[8], NULL, 0), "0.0.0.0", parv[9]); } else if (parc==11) { return do_user(nick, cptr, sptr, parv[5], parv[6], parv[7], strtoul(parv[8], NULL, 0), parv[9], parv[10]); } } } else if (sptr->name[0]) { #ifdef DONT_CHECK_QLINE_REMOTE if (MyConnect(sptr)) { #endif if ((ban = check_mask_simbanned(nick, SBAN_NICK))) { #ifndef DONT_CHECK_QLINE_REMOTE if (!MyConnect(sptr)) sendto_realops("Restricted nick %s from %s on %s", nick, (*sptr->name != 0 && !IsServer(sptr)) ? sptr->name : "<unregistered>", (sptr->user == NULL) ? ((IsServer(sptr)) ? parv[6] : me.name) : sptr->user->server); #endif if (MyConnect(sptr) && (!IsServer(cptr)) && (!IsOper(cptr)) && (!IsULine(sptr))) { sendto_one(sptr, err_str(ERR_ERRONEUSNICKNAME), me.name, BadPtr(parv[0]) ? "*" : parv[0], nick, BadPtr(ban->reason) ? "Erroneous Nickname" : ban->reason); if (call_hooks(CHOOK_FORBID, cptr, nick, ban) != FLUSH_BUFFER) sendto_realops_lev(REJ_LEV, "Forbidding restricted nick %s from %s", nick, get_client_name(cptr, FALSE)); return 0; } } #ifdef DONT_CHECK_QLINE_REMOTE } #endif if (MyConnect(sptr)) { if (IsRegisteredUser(sptr)) { /* before we change their nick, make sure they're not banned * on any channels, and!! make sure they're not changing to * a banned nick -sed */ /* a little cleaner - lucas */ for (lp = sptr->user->channel; lp; lp = lp->next) { if (can_send(sptr, lp->value.chptr, NULL)) { sendto_one(sptr, err_str(ERR_BANNICKCHANGE), me.name, sptr->name, lp->value.chptr->chname); return 0; } if (nick_is_banned(lp->value.chptr, nick, sptr) != NULL) { sendto_one(sptr, err_str(ERR_BANONCHAN), me.name, sptr->name, nick, lp->value.chptr->chname); return 0; } } #ifdef ANTI_NICK_FLOOD if ((sptr->last_nick_change + MAX_NICK_TIME) < NOW) sptr->number_of_nick_changes = 0; sptr->last_nick_change = NOW; sptr->number_of_nick_changes++; if (sptr->number_of_nick_changes > MAX_NICK_CHANGES && !IsAnOper(sptr)) { sendto_one(sptr, ":%s NOTICE %s :*** Notice -- Too many nick " "changes. Wait %d seconds before trying again.", me.name, sptr->name, MAX_NICK_TIME); return 0; } #endif /* If it changed nicks, -r it */ if ((sptr->umode & UMODE_r) && (mycmp(parv[0], nick) != 0)) { unsigned int oldumode; char mbuf[BUFSIZE]; oldumode = sptr->umode; sptr->umode &= ~UMODE_r; send_umode(sptr, sptr, oldumode, ALL_UMODES, mbuf); } /* LOCAL NICKHANGE */ /* * Client just changing his/her nick. If he/she is on a * channel, send note of change to all clients on that channel. * Propagate notice to other servers. */ /* if the nickname is different, set the TS */ if (mycmp(parv[0], nick)) { sptr->tsinfo = newts ? newts : (ts_val) timeofday; } sendto_common_channels(sptr, ":%s NICK :%s", parv[0], nick); if (sptr->user) { add_history(sptr, 1); sendto_serv_butone(cptr, ":%s NICK %s :%ld", parv[0], nick, sptr->tsinfo); } } } else { /* REMOTE NICKCHANGE */ /* * Client just changing his/her nick. If he/she is on a * channel, send note of change to all clients on that channel. * Propagate notice to other servers. */ /* if the nickname is different, set the TS */ if (mycmp(parv[0], nick)) { sptr->tsinfo = newts ? newts : (ts_val) timeofday; } sendto_common_channels(sptr, ":%s NICK :%s", parv[0], nick); if (sptr->user) { add_history(sptr, 1); sendto_serv_butone(cptr, ":%s NICK %s :%ld", parv[0], nick, sptr->tsinfo); } /* If it changed nicks, -r it */ if (mycmp(parv[0], nick)) sptr->umode &= ~UMODE_r; /* * Flush the banserial for the channels the user is in, since this * could be a SVSNICK induced nick change, which overrides any ban * checking on the originating server. */ flush_user_banserial(sptr); } /* Remove dccallow entries for users who don't share common channel(s) unless they only change their nick capitalization -Kobi_S */ if(sptr->user && mycmp(parv[0], nick)) { for(lp = sptr->user->dccallow; lp; lp = lp2) { lp2 = lp->next; if(lp->flags == DCC_LINK_ME) continue; if(!find_shared_chan(sptr, lp->value.cptr)) { sendto_one(lp->value.cptr, ":%s %d %s :%s has been removed from " "your DCC allow list for signing off", me.name, RPL_DCCINFO, lp->value.cptr->name, parv[0]); del_dccallow(lp->value.cptr, sptr, 1); } } } } else { /* Client setting NICK the first time */ if (MyConnect(sptr)) { if ((ban = check_mask_simbanned(nick, SBAN_NICK))) { if (MyConnect(sptr) && (!IsServer(cptr)) && (!IsOper(cptr)) && (!IsULine(sptr))) { sendto_one(sptr, err_str(ERR_ERRONEUSNICKNAME), me.name, BadPtr(parv[0]) ? "*" : parv[0], nick, BadPtr(ban->reason) ? "Erroneous Nickname" : ban->reason); if (call_hooks(CHOOK_FORBID, cptr, nick, ban) != FLUSH_BUFFER) sendto_realops_lev(REJ_LEV, "Forbidding restricted nick %s from %s", nick, get_client_name(cptr, FALSE)); return 0; } } } strcpy(sptr->name, nick); sptr->tsinfo = timeofday; if (sptr->user) { /* USER already received, now we have NICK */ if (register_user(cptr, sptr, nick, sptr->user->username, NULL) == FLUSH_BUFFER) return FLUSH_BUFFER; } } /* Finally set new nick name. */ if (sptr->name[0]) { del_from_client_hash_table(sptr->name, sptr); samenick = mycmp(sptr->name, nick) ? 0 : 1; if (IsPerson(sptr)) { if (!samenick) hash_check_watch(sptr, RPL_LOGOFF); #ifdef RWHO_PROBABILITY probability_change(sptr->name, nick); #endif } } strcpy(sptr->name, nick); add_to_client_hash_table(nick, sptr); if (IsPerson(sptr) && !samenick) hash_check_watch(sptr, RPL_LOGON); return 0; }
/* * mr_pass - registration message handler */ int mr_pass(struct Client* cptr, struct Client* sptr, int parc, char* parv[]) { const char* password; char* loc = NULL; char* locargv[3] = {NULL, NULL, NULL}; assert(0 != cptr); assert(cptr == sptr); assert(!IsRegistered(sptr)); /* TODO: For protocol negotiation */ #if 0 if (ircd_strcmp(password,"PROT")==0) { /* Do something here */ } #endif if (parc == 2 && parv[1][0] == ':') { /* * All hail code duplication! * * Here we emulate parse_client, for the benefit of buggy clients. * If there's only one arg that starts with a literal ':', we * split it again. Thus, a valid line might be: * PASS ::X username :pass phrase * or * PASS ::I-line-pass X username :pass phrase * or * PASS ::I-Line-pass /X/username/passphrase * PASS ::/X/username/passphrase * PASS ::/username/passphrase * PASS ::/passphrase ??pull username from user/ident string?? * * after a while we'll remove the non '/' version * when noone is using it anymore, and clean * this function up significantly. */ char* s = &parv[1][1]; parc = 1; for (;;) { while (*s == ' ') *s++ = 0; if (*s == 0) break; if (*s == ':') { parv[parc++] = s + 1; break; } parv[parc++] = s; if (parc >= MAXPARA) break; while (*s != ' ' && *s) s++; } parv[parc] = NULL; } password = parc > 1 ? parv[1] : 0; if (!EmptyString(password)) ircd_strncpy(cli_passwd(cptr), password, PASSWDLEN); if (feature_bool(FEAT_LOGIN_ON_CONNECT) && !cli_loc(cptr)) { /* Check for leading '/' to indicate new-fangled LOC syntax */ if (parc > 1 && parv[1][0] == '/') loc = parv[1]+1; else if (parc > 2 && parv[2][0] == '/') loc = parv[2]+1; if (loc && *loc) { /* Split loc up into locargv[0 through 2] */ int locargc = 0; locargv[locargc++] = loc; for ( ; *loc; loc++) { if (*loc == '/') { *loc = 0; locargv[locargc++] = loc + 1; if (locargc > 2) break; } } if (locargc == 2) { /* Missing service nick, fill in default and shift arguments up */ locargv[2] = locargv[1]; locargv[1] = locargv[0]; locargv[0] = (char *)feature_str(FEAT_LOC_DEFAULT_SERVICE); } } else if (parc > 3) { /* Old style for backward compatability: */ locargv[0] = parv[parc - 3]; locargv[1] = parv[parc - 2]; locargv[2] = parv[parc - 1]; } if (locargv[0] && *locargv[0] && locargv[1] && *locargv[1]) { cli_loc(cptr) = MyMalloc(sizeof(struct LOCInfo)); memset(cli_loc(cptr), 0, sizeof(struct LOCInfo)); cli_loc(cptr)->cookie = 0; ircd_strncpy(cli_loc(cptr)->service, locargv[0], NICKLEN); ircd_strncpy(cli_loc(cptr)->account, locargv[1], ACCOUNTLEN); if (locargv[2] && *locargv[2]) ircd_strncpy(cli_loc(cptr)->password, locargv[2], ACCPASSWDLEN); else ircd_strncpy(cli_loc(cptr)->password, "", ACCPASSWDLEN); } /* handle retries */ if ((cli_name(cptr))[0] && cli_cookie(cptr) == COOKIE_VERIFIED) return register_user(cptr, cptr, cli_name(cptr), cli_user(cptr)->username); } return 0; }
int main(int argc, char **argv) { //parse command line arguments benchmark_t *setup = parse_args(argc,argv); // setup user connection mio_conn_t *conn = mio_conn_new(); mio_connect(setup -> user, setup -> pass, MIO_LEVEL_DEBUG, NULL, NULL, conn); // - register new publishers // - connect new publishers // - register new publishers event nodes int user_index, error, node_index; char tmp_username[UUID_LENGTH]; char tmp_password[UUID_LENGTH]; char *tmp_node_id,*tmp_jid; mio_response_t *response = NULL; uuid_t tmp_uuid; srand(time(NULL)); thread_args_t *thread_args; publishers = malloc(setup -> n_publishers * sizeof(mio_conn_t*)); memset(publishers, 0x0, setup -> n_publishers * sizeof(mio_conn_t*)); publish_nodes = (char***) malloc(setup -> n_publishers * sizeof(char**)); publish_count = (int**) malloc(setup -> n_publishers *sizeof(int*)); for (user_index = 0; user_index < setup -> n_publishers; user_index++) { uuid_generate(tmp_uuid); uuid_unparse(tmp_uuid,tmp_username); uuid_generate(tmp_uuid); uuid_unparse(tmp_uuid,tmp_password); error = register_user(conn, tmp_username,tmp_password); publishers[user_index] = mio_conn_new(); if (error) { printf("error registering user %s \n", tmp_username); } else { tmp_jid = malloc(100); sprintf(tmp_jid,"%s@%s", tmp_username, setup -> server); mio_connect(tmp_jid, tmp_password, MIO_LEVEL_ERROR, NULL,NULL,publishers[user_index]); } publish_nodes[user_index] = malloc(setup -> publish_factor * sizeof(char*)); for (node_index = 0; node_index < setup -> publish_factor; node_index++) { tmp_node_id = malloc(UUID_LENGTH * sizeof(char)); uuid_generate(tmp_uuid); uuid_unparse(tmp_uuid,tmp_node_id); publish_nodes[user_index][node_index] = tmp_node_id; response = mio_response_new(); mio_node_create(publishers[user_index], tmp_node_id, "", NULL, response); mio_response_free(response); tmp_node_id = NULL; } publish_count[user_index] = (int*) malloc(sizeof(int)*setup -> publish_factor); memset(publish_count[user_index],0x0,sizeof(int)*setup -> publish_factor); memset(tmp_username,0x0,UUID_LENGTH); memset(tmp_password,0x0,UUID_LENGTH); } // register new subscribers // connect new subscribers // randomly assign the nodes to subscribe to // initialize count matrix subscribers = malloc(setup -> n_subscribers * sizeof(mio_conn_t*)); memset(subscribers, 0x0, setup -> n_subscribers * sizeof(mio_conn_t*)); subscribe_nodes = (char***) malloc(setup -> n_subscribers * sizeof(char**)); subscribe_count = (int**) malloc(setup -> n_subscribers *sizeof(int*)); printf("%d\n", setup -> n_subscribers); for (user_index = 0; user_index < setup -> n_subscribers; user_index++) { uuid_generate(tmp_uuid); uuid_unparse(tmp_uuid,tmp_username); uuid_generate(tmp_uuid); uuid_unparse(tmp_uuid,tmp_password); subscribers[user_index] = mio_conn_new(); error = register_user(conn, tmp_username,tmp_password); if (error) { printf("error registering user %s \n", tmp_username); } else { tmp_jid = malloc(100); sprintf(tmp_jid,"%s@%s", tmp_username,setup -> server); mio_connect(tmp_jid, tmp_password, MIO_LEVEL_ERROR, NULL,NULL,subscribers[user_index]); } subscribe_nodes[user_index] = malloc(setup -> subscribe_factor * sizeof(char*)); int pub_index = (user_index * setup -> subscribe_factor)/(setup -> publish_factor) % setup -> n_publishers; int event_index = (user_index * setup -> subscribe_factor) % (setup -> publish_factor); for (node_index = 0; node_index < setup -> subscribe_factor; node_index++) { printf("%d node, %d pub, %d event\n", node_index, pub_index, event_index); tmp_node_id = publish_nodes[pub_index][ event_index]; subscribe_nodes[user_index][node_index] = tmp_node_id; response = mio_response_new(); error = mio_subscribe(subscribers[user_index], tmp_node_id, response); mio_response_free(response); event_index++; pub_index += event_index / setup -> publish_factor; pub_index = pub_index % setup -> n_publishers; event_index = event_index % setup -> publish_factor; } subscribe_count[user_index] = (int*) malloc(sizeof(int)*setup -> subscribe_factor); memset(subscribe_count[user_index],0x0,sizeof(int)*setup -> subscribe_factor); memset(tmp_username,0x0,UUID_LENGTH); memset(tmp_password,0x0,UUID_LENGTH); } publish_threads = (pthread_t*) malloc(setup -> n_publishers*sizeof(pthread_t)); subscribe_threads = (pthread_t*) malloc(setup -> n_publishers*sizeof(pthread_t)); // spawn process for each subscriber // spawn process for each publisher for (user_index = 0; user_index < setup -> n_subscribers; user_index++) { thread_args = (thread_args_t*) malloc(sizeof(thread_args_t)); thread_args -> user_index = user_index; thread_args -> setup = setup; pthread_create(&subscribe_threads[user_index], NULL, (void*) &subscriber_thread, thread_args); } for (user_index = 0; user_index < setup -> n_publishers; user_index++) { thread_args = (thread_args_t*) malloc(sizeof(thread_args_t)); thread_args -> user_index = user_index; thread_args -> setup = setup; pthread_create(&publish_threads[user_index], NULL, (void*) &publisher_thread, thread_args); } // have subscribers and publishers increment // kill all threads after proveided time long elapsed = 0; long last_time = time(NULL), time_tmp; while(elapsed < setup -> time) { sleep(setup -> time /10); time_tmp = time(NULL); elapsed += time_tmp - last_time; last_time = time_tmp; } for (user_index = 0; user_index < setup -> n_subscribers; user_index++) { pthread_cancel(subscribe_threads[user_index]); } for (user_index = 0; user_index < setup -> n_publishers; user_index++) { pthread_cancel(publish_threads[user_index]); } print_results(setup); return 0; }
int main(int argc, char *argv[]) { CREATE_LOG("./"); auto desc = create_descriptions(); auto vm = parse_options(argc, argv, desc); if(vm.count("help")) { std::cout << desc << std::endl; return 1; } Botan::LibraryInitializer init; auto host = vm["host"].as<std::string>(); auto port = vm["port"].as<std::string>(); auto pass = vm.count("pass") ? vm["pass"].as<std::string>() : prompt_pass(); auto key = vm["key"].as<std::string>(); auto pkey = load_private_key(key, pass); CHECK(pkey); //it is important the tcp_connection manager is created before //the input tcp_connection is made. This is because tcp on //linux requires that binds to the same port are made before //a listen is made. n::connection_manager con{POOL_SIZE, port}; sc::session_library sec{*pkey}; user_info_map users; u::bytes data; while(true) try { n::endpoint ep; if(!con.receive(ep, data)) { u::sleep_thread(THREAD_SLEEP); continue; } //decrypt message auto sid = n::make_address_str(ep); data = sec.decrypt(sid, data); //parse message m::message m; u::decode(data, m); if(m.meta.type == ms::GREET_REGISTER) { ms::greet_register r{m}; register_user(con, sec, ep, r, users); } else if(m.meta.type == ms::GREET_FIND_REQUEST) { ms::greet_find_request r{m}; find_user(con, sec, ep, r, users); } else if(m.meta.type == ms::GREET_KEY_REQUEST) { ms::greet_key_request r{m}; send_pub_key(con, sec, ep, r, users, *pkey); } } catch(std::exception& e) { LOG << "error parsing message: " << e.what() << std::endl; LOG << "message: " << u::to_str(data) << std::endl; } catch(...) { LOG << "unknown error parsing message: " << std::endl; LOG << "message: " << u::to_str(data) << std::endl; } }
/* *Main thread for each client. Receives all messages *and passes the data off to the correct function. Receives *a pointer to the file descriptor for the socket the thread *should listen on */ void *client_receive(void *ptr) { int client = *(int *) ptr; int received; int logged_in = 0; packet in_pkt, *client_message_ptr = &in_pkt; while (1) { received = recv(client, &in_pkt, sizeof(packet), 0); if (received) { debugPacket(client_message_ptr); // Responses to not logged in clients if (!logged_in) { if(in_pkt.options == REGISTER) { logged_in = register_user(&in_pkt, client); } else if(in_pkt.options == LOGIN) { logged_in = login(&in_pkt, client); } else if(in_pkt.options == EXIT) { close(client); return NULL; } else { sendError("Not logged in.", client); } } // Responses to logged in clients else if (logged_in) { // Handle option messages for logged in client if (in_pkt.options < 1000) { if(in_pkt.options == REGISTER) { sendError("You may not register while logged in.", client); } else if(in_pkt.options == SETPASS) { set_pass(&in_pkt, client); } else if(in_pkt.options == SETNAME) { set_name(&in_pkt, client); } else if(in_pkt.options == LOGIN) { sendError("Already logged in.", client); } else if(in_pkt.options == EXIT) { exit_client(&in_pkt, client); return NULL; } else if(in_pkt.options == INVITE) { invite(&in_pkt, client); } else if(in_pkt.options == JOIN) { join(&in_pkt, client); } else if(in_pkt.options == LEAVE) { leave(&in_pkt, client); } else if(in_pkt.options == GETALLUSERS) { get_active_users(client); } else if(in_pkt.options == GETUSERS) { get_room_users(&in_pkt, client); } else if(in_pkt.options == GETUSER) { user_lookup(&in_pkt, client); } else if(in_pkt.options == GETROOMS) { get_room_list(client); } else if(in_pkt.options == GETMOTD) { sendMOTD(client); } else if(in_pkt.options == 0) { printf("%s --- Error:%s Abrupt disconnect on logged in client.\n", RED, NORMAL); exit_client(&in_pkt, client); return NULL; } else { printf("%s --- Error:%s Unknown message received from client.\n", RED, NORMAL); } } // Handle conversation message for logged in client else { // Will be treated as a message packet, safe to santize entire buffer sanitizeInput((void *)&in_pkt.buf, 0); send_message(&in_pkt, client); } } memset(&in_pkt, 0, sizeof(packet)); } } return NULL; }
void process_data(const std::string &data, const std::string &dbpath, WOLFSSL *sslconn) { //format is cmd:user:secretkey:<possible b64 string> std::vector<std::string> cmdparts; std::stringstream ss(data); std::string part; std::string cmd; std::string user; std::string secret; std::string b64dat; char reply; while(std::getline(ss,part,':')) { if (part != "" && part != " ") cmdparts.push_back(part); } if (cmdparts.size() < 3) { std::cout<<"[-] Client sent an invalid command"<<std::endl; return; } if (cmdparts.size() >= 3) { cmd = cmdparts[0]; user = cmdparts[1]; secret = cmdparts[2]; } if (cmdparts.size() == 4) { b64dat = cmdparts[3]; } //std::cout<<"[DEBUG] "<<data<<std::endl; /* client wishes to register */ if (cmd == "REGISTER") { if (cmdparts.size() == 3) { if (!register_user(user,secret,dbpath)) { std::cout<<"[-] "<<"Failed to register user: "******"[+] "<<"Successfully registered user: "******"[-] Client sent an invalid command"<<std::endl; } if (wolfSSL_write(sslconn, &reply, sizeof(char)) != sizeof(char)) std::cout<< "[-] " << "Failed to notify client of registration status" << std::endl; return; } bool authsuccess = auth_user(user,secret,dbpath); Json::Value root; Json::Value val; Json::StreamWriterBuilder builder; std::string tmp = ""; int loginattempts = 0; if (!read_user_db(&root,dbpath)) return; /* authenticate user before any command processing */ if (!authsuccess) { std::cout<<"[-] "<<user<<" failed to authenticate"<<std::endl; if (root["users"].isMember(user)) { if (root["users"][user].isMember("loginattempts")) { val = root["users"][user]["loginattempts"]; tmp = Json::writeString(builder,val); loginattempts = atoi(tmp.c_str()); //DEBUG //std::cout << tmp << std::endl; //std::cout << loginattempts << std::endl; } loginattempts += 1; root["users"][user]["loginattempts"] = loginattempts; if (!write_user_db(&root, dbpath)) return; } return; } else { if (root["users"].isMember(user)) root["users"][user]["loginattempts"] = 0; if (write_user_db(&root, dbpath)) std::cout<<"[+] "<<user<<" authenticated successfully"<<std::endl; else std::cout << "[-] Failed to write to user database!" << std::endl; } /* client wishes to upload their database */ if (cmd == "UPLOAD") { if (cmdparts.size() == 4) { if (!update_file(user,b64dat)) { std::cout<<"[-] Failed to update "<<user<<"'s"<<" database"<<std::endl; reply = 0; } else { std::cout<<"[+] Updated "<<user<<"'s"<<" database"<<std::endl; reply = 1; } } else { std::cout<<"[-] Client sent an invalid command"<<std::endl; } if (wolfSSL_write(sslconn, &reply, sizeof(char)) != sizeof(char)) std::cout<< "[-] " << "Failed to notify client of chpass status" << std::endl; } /* client wishes to download their database */ else if (cmd == "DOWNLOAD") { if (cmdparts.size() == 3) { if (!send_file(user,sslconn)) std::cout<<"[-] Failed to send "<<user<<"'s"<<" database"<<std::endl; else std::cout<<"[+] Sent "<<user<<"'s"<<" database"<<std::endl; } else { std::cout<<"[-] Client sent an invalid command"<<std::endl; } } else if (cmd == "CHPASS") { //CHPASS:user:curpass:newpass\n if (cmdparts.size() == 4) { //it isn't actually b64-encoded, it's hex.. std::string newpass = b64dat; if (!change_user_pass(user,newpass,dbpath)) { reply = 0; std::cout<<"[-] Failed to change "<<user<<"'s"<<" password"<<std::endl; } else { reply = 1; std::cout<<"[+] Successfully changed "<<user<<"'s"<<" password"<<std::endl; } } else { std::cout<<"[-] Client sent an invalid command"<<std::endl; } if (wolfSSL_write(sslconn, &reply, sizeof(char)) != sizeof(char)) std::cout<< "[-] " << "Failed to notify client of chpass status" << std::endl; } else if (cmd == "TIMESTAMP") { //TIMESTAMP:USER:PASS:time_t value if (cmdparts.size() == 4) { struct stat filestats; std::string userdbpath = user + "_keylocker.db"; //time_t gotmodtime; time_t modtime; std::cout << "[*] Got timestamp request from " << user << std::endl; //file not found, send timestamp of 0 if (stat(userdbpath.c_str(), &filestats) == -1) { std::cout << "[*] " << user << " does not have a database on this server" << std::endl; modtime = 0; } else modtime = filestats.st_mtime; if (wolfSSL_write(sslconn, &modtime, sizeof(time_t)) != sizeof(time_t)) { std::cout << "[-] Failed to notify " << user << " of timestamp" << std::endl; } } else std::cout<<"[-] Client sent an invalid command"<<std::endl; } /* client sent invalid command */ else { std::cout<<"[-] Client sent an invalid command"<<std::endl; } return; }
/* * read_iauth * * read and process data from the authentication slave process. */ void read_iauth(void) { static char obuf[READBUF_SIZE+1], last = '?'; static int olen = 0, ia_dbg = 0; char buf[READBUF_SIZE+1], *start, *end, tbuf[BUFSIZ]; aClient *cptr; int i; if (adfd == -1) { olen = 0; return; } while (1) { if (olen) bcopy(obuf, buf, olen); if ((i = recv(adfd, buf+olen, READBUF_SIZE-olen, 0)) <= 0) { if (errno != EAGAIN && errno != EWOULDBLOCK) { sendto_flag(SCH_AUTH, "Aiiie! lost slave authentication process (errno = %d)", errno); close(adfd); adfd = -1; olen = 0; start_iauth(0); } break; } olen += i; buf[olen] = '\0'; start = buf; while ((end = index(start, '\n'))) { *end++ = '\0'; last = *start; if (*start == '>') { sendto_flag(SCH_AUTH, "%s", start+1); start = end; continue; } if (*start == 'G') { ia_dbg = atoi(start+2); if (ia_dbg) sendto_flag(SCH_AUTH,"ia_dbg = %d",ia_dbg); start = end; continue; } if (*start == 'O') /* options */ { iauth_options = 0; if (strchr(start+2, 'A')) iauth_options |= XOPT_EARLYPARSE; if (strchr(start+2, 'R')) iauth_options |= XOPT_REQUIRED; if (strchr(start+2, 'T')) iauth_options |= XOPT_NOTIMEOUT; if (strchr(start+2, 'W')) iauth_options |= XOPT_EXTWAIT; if (iauth_options) sendto_flag(SCH_AUTH, "iauth options: %x", iauth_options); start = end; continue; } if (*start == 'V') /* version */ { if (iauth_version) MyFree(iauth_version); iauth_version = mystrdup(start+2); sendto_flag(SCH_AUTH, "iauth version %s running.", iauth_version); start = end; sendto_iauth("0 M %s", me.name); continue; } if (*start == 'a') { aExtCf *ectmp; while ((ectmp = iauth_conf)) { iauth_conf = iauth_conf->next; MyFree(ectmp->line); MyFree(ectmp); } /* little lie.. ;) */ sendto_flag(SCH_AUTH, "New iauth configuration."); start = end; continue; } if (*start == 'A') { aExtCf **ectmp = &iauth_conf; while (*ectmp) ectmp = &((*ectmp)->next); *ectmp = (aExtCf *) MyMalloc(sizeof(aExtCf)); (*ectmp)->line = mystrdup(start+2); (*ectmp)->next = NULL; start = end; continue; } if (*start == 's') { aExtData *ectmp; while ((ectmp = iauth_stats)) { iauth_stats = iauth_stats->next; MyFree(ectmp->line); MyFree(ectmp); } iauth_stats = (aExtData *) MyMalloc(sizeof(aExtData)); iauth_stats->line = MyMalloc(60); sprintf(iauth_stats->line, "iauth modules statistics (%s)", myctime(timeofday)); iauth_stats->next = (aExtData *) MyMalloc(sizeof(aExtData)); iauth_stats->next->line = MyMalloc(60); sprintf(iauth_stats->next->line, "spawned: %d, current options: %X (%.11s)", iauth_spawn, iauth_options, (iauth_version) ? iauth_version : "???"); iauth_stats->next->next = NULL; start = end; continue; } if (*start == 'S') { aExtData **ectmp = &iauth_stats; while (*ectmp) ectmp = &((*ectmp)->next); *ectmp = (aExtData *) MyMalloc(sizeof(aExtData)); (*ectmp)->line = mystrdup(start+2); (*ectmp)->next = NULL; start = end; continue; } if (*start != 'U' && *start != 'u' && *start != 'o' && *start != 'K' && *start != 'k' && *start != 'D') { sendto_flag(SCH_AUTH, "Garbage from iauth [%s]", start); sendto_iauth("-1 E Garbage [%s]", start); /* ** The above should never happen, but i've seen it ** occasionnally, so let's try to get more info ** about it! -kalt */ sendto_flag(SCH_AUTH, "last=%u start=%x end=%x buf=%x olen=%d i=%d", last, start, end, buf, olen, i); sendto_iauth( "-1 E last=%u start=%x end=%x buf=%x olen=%d i=%d", last, start, end, buf, olen, i); start = end; continue; } if ((cptr = local[i = atoi(start+2)]) == NULL) { /* this is fairly common and can be ignored */ if (ia_dbg) { sendto_flag(SCH_AUTH, "Client %d is gone.", i); sendto_iauth("%d E Gone [%s]", i, start); } start = end; continue; } #ifndef INET6 sprintf(tbuf, "%c %d %s %u ", start[0], i, inetntoa((char *)&cptr->ip), cptr->port); #else sprintf(tbuf, "%c %d %s %u ", start[0], i, inetntop(AF_INET6, (char *)&cptr->ip, ipv6string, sizeof(ipv6string)), cptr->port); #endif if (strncmp(tbuf, start, strlen(tbuf))) { /* this is fairly common and can be ignored */ if (ia_dbg) { sendto_flag(SCH_AUTH, "Client mismatch: %d [%s] != [%s]", i, start, tbuf); sendto_iauth("%d E Mismatch [%s] != [%s]", i, start, tbuf); } start = end; continue; } if (start[0] == 'U') { if (*(start+strlen(tbuf)) == '\0') { sendto_flag(SCH_AUTH, "Null U message! %d [%s]", i, start); sendto_iauth("%d E Null U [%s]", i, start); start = end; continue; } if (cptr->auth != cptr->username) { istat.is_authmem -= strlen(cptr->auth) + 1; istat.is_auth -= 1; MyFree(cptr->auth); } cptr->auth = mystrdup(start+strlen(tbuf)); set_clean_username(cptr); cptr->flags |= FLAGS_GOTID; } else if (start[0] == 'u') { if (*(start+strlen(tbuf)) == '\0') { sendto_flag(SCH_AUTH, "Null u message! %d [%s]", i, start); sendto_iauth("%d E Null u [%s]", i, start); start = end; continue; } if (cptr->auth != cptr->username) { istat.is_authmem -= strlen(cptr->auth) + 1; istat.is_auth -= 1; MyFree(cptr->auth); } cptr->auth = MyMalloc(strlen(start+strlen(tbuf)) + 2); *cptr->auth = '-'; strcpy(cptr->auth+1, start+strlen(tbuf)); set_clean_username(cptr); cptr->flags |= FLAGS_GOTID; } else if (start[0] == 'o') { if (!WaitingXAuth(cptr)) { sendto_flag(SCH_AUTH, "Early o message discarded!"); sendto_iauth("%d E Early o [%s]", i,start); start = end; continue; } if (cptr->user == NULL) { /* just to be safe */ sendto_flag(SCH_AUTH, "Ack! cptr->user is NULL"); start = end; continue; } strncpyzt(cptr->user->username, tbuf, USERLEN+1); } else if (start[0] == 'D') { /*authentication finished*/ ClearXAuth(cptr); SetDoneXAuth(cptr); if (WaitingXAuth(cptr)) { ClearWXAuth(cptr); register_user(cptr, cptr, cptr->name, cptr->user->username); } else ClearWXAuth(cptr); } else { char *reason; /* Copy kill reason received from iauth */ reason = strstr(start, " :"); if (reason && (reason + 2 != '\0')) { if (cptr->reason) { MyFree(cptr->reason); } cptr->reason = mystrdup(reason + 2); } /* ** mark for kill, because it cannot be killed ** yet: we don't even know if this is a server ** or a user connection! */ if (start[0] == 'K') cptr->exitc = EXITC_AREF; else cptr->exitc = EXITC_AREFQ; /* should also check to make sure it's still an unregistered client.. */ /* Finally, working after registration. --B. */ if (IsRegisteredUser(cptr)) { if (cptr->exitc == EXITC_AREF) { sendto_flag(SCH_LOCAL, "Denied after connection " "from %s.", get_client_host(cptr)); } (void) exit_client(cptr, cptr, &me, cptr->reason ? cptr->reason : "Denied access"); } } start = end; } olen -= start - buf; if (olen) memcpy(obuf, start, olen); } }
int main(int argc, char *argv[]) { CREATE_LOG("./"); auto desc = create_descriptions(); auto vm = parse_options(argc, argv, desc); if(vm.count("help")) { std::cout << desc << std::endl; return 1; } Botan::LibraryInitializer init; auto host = vm["host"].as<std::string>(); auto port = vm["port"].as<int>(); auto pass = vm.count("pass") ? vm["pass"].as<std::string>() : prompt_pass(); auto key = vm["key"].as<std::string>(); auto pkey = load_private_key(key, pass); CHECK(pkey); n::connection_manager con{POOL_SIZE, static_cast<n::port_type>(port)}; sc::encrypted_channels sec{*pkey}; user_info_map users; u::bytes data; while(true) try { n::endpoint ep; if(!con.receive(ep, data)) { u::sleep_thread(THREAD_SLEEP); continue; } //decrypt message auto sid = n::make_address_str(ep); sc::encryption_type et; data = sec.decrypt(sid, data, et); data = u::uncompress(data); //parse message m::message m; u::decode(data, m); if(m.meta.type == ms::GREET_REGISTER) { if(et != sc::encryption_type::asymmetric) continue; ms::greet_register r{m}; register_user(con, sec, ep, r, users); } else if(m.meta.type == ms::GREET_FIND_REQUEST) { if(et != sc::encryption_type::asymmetric) continue; ms::greet_find_request r{m}; find_user(con, sec, ep, r, users); } else if(m.meta.type == ms::GREET_KEY_REQUEST) { ms::greet_key_request r{m}; send_pub_key(con, sec, ep, r, users, *pkey); } } catch(std::exception& e) { LOG << "error parsing message: " << e.what() << std::endl; } catch(...) { LOG << "unknown error parsing message: " << std::endl; } }
int main() { //register_user("ezhuang", "john1990", "test"); //register_user("hahaha","dadada","test"); //register_user("ddd","poo","test"); //match_user("ezhuang", "john1990", "test"); //match_user("hahaha","dadada","test"); //match_user("ezhuang", "john1990", "test"); //delete_user("hahaha","dadada","test"); printf("Available commands:\n(1) register_user\n(2) delete_user\n(3) is_user_valid\n(4) match_user\n(5) change_user_password\n(6) quit\n\n\n"); unsigned char command[1024]; int operation_status ; while(1) { printf("enter a command: "); scanf("%s",command) ; // printf("\n") ; operation_status = OKAY ; if(!strcmp(command,"register_user")) { printf("username: "******"%s",username) ; printf("password: "******"%s",password) ; printf("password file name: "); unsigned char pFile[1024] ; scanf("%s",pFile); operation_status = register_user(username,password,pFile) ; } else if(!strcmp(command,"delete_user")) { printf("username: "******"%s",username) ; printf("password: "******"%s",password) ; printf("password file name: "); unsigned char pFile[1024] ; scanf("%s",pFile); operation_status = delete_user(username,password, pFile) ; } else if(!strcmp(command,"is_user_valid")) { printf("username: "******"%s",username) ; printf("password file name: "); unsigned char pFile[1024] ; scanf("%s",pFile); operation_status = is_user_valid(username,pFile) ; } else if(!strcmp(command,"match_user")) { printf("username: "******"%s",username) ; printf("password: "******"%s",password) ; printf("password file name: "); unsigned char pFile[1024] ; scanf("%s",pFile); operation_status = match_user(username,password,pFile) ; } else if(!strcmp(command,"change_user_password")) { printf("username: "******"%s",username) ; printf("current password: "******"%s",password) ; printf("new password: "******"%s",npassword) ; printf("password file name: "); unsigned char pFile[1024] ; scanf("%s",pFile); operation_status = change_user_password(username,password,npassword, pFile) ; } else if(!strcmp(command,"quit")) { printf("INFO: Got the quit command\n"); printf("Program terminating\n"); break; } else { printf("ERROR: Unknown command %s\n",command); printf("INFO: Ignoring command\n") ; } if(operation_status == ERROR) printf("Operation %s failed\n",command) ; } return 0; }
int main() { char username[500]; int is_admin = 0; char password[500]; int logged_in = 0; char flag[250]; char user[500]; char pw[500]; setbuf(stdout, NULL); printf("Welcome to the FlagStore!\n"); while (1) { printf("Choose an action:\n"); printf("> %s: 1\n> %s: 2\n> %s: 3\n> %s: 4\n", "regiser", "login", "get_flag", "store_flag"); int answer = 0; scanf("%d", &answer); switch(answer) { case 1: printf("Enter an username:"******"%s", username); printf("Enter a password:"******"%s", password); if(strcmp(username, "admin") == 0) { printf("Sorry, admin user already registered\n"); break; } if(strlen(password) < 6) { printf("Sorry, password too short\n"); break; } register_user(username, password); printf("User %s successfully registered. You can login now!\n", username); break; case 2: printf("Username:"******"%499s", user); printf("Password:"******"%499s", pw); if(check_login(user, pw, username, password) == -1) { printf("Wrong credentials!\n"); break; } logged_in = 1; printf("You're now authenticated!\n"); break; case 3: if(logged_in == 0) { printf("Please login first!\n"); break; } if(is_admin != 0) { strcpy(flag, FLAG); } printf("Your flag: %s\n", flag); break; case 4: if(logged_in == 0) { printf("Please login first!\n"); break; } printf("Enter your flag:"); scanf("%s",flag); printf("Flag saved!\n"); break; default: printf("Wrong option\nGood bye\n"); return -1; } } }
/* Main Engine. * Coordinates all the required setup, sending & receiving from users */ void Server::start () { // client address structure (to be recieved) struct sockaddr_in client; socklen_t client_len = sizeof (struct sockaddr_storage); // message structure im_message msg; size_t msg_len = sizeof (msg); cout << "Server: Starting... \n"; // Setup server if (!setup_server ()) { cerr << "Server: Setup Failed\n "; return; } cout << "Server: Start Successful\n"; // receive message from users while (1) { int len = 0; memset (&msg, 0, sizeof (msg)); len = recvfrom (master_socket, &msg, msg_len, 0, (struct sockaddr *) &client, &client_len); if (len == -1) continue; else if (len != msg_len) { // Some problem in the message sent cerr << "Some problem occurred in sending the message\n"; } else { #ifdef _DEBUG_ char host[NI_MAXHOST], service[NI_MAXSERV]; int s = getnameinfo ((struct sockaddr *) &client, client_len, host, NI_MAXHOST, service, NI_MAXSERV, NI_NUMERICSERV); if (s == 0) printf ("Received %d bytes from %s:%s\n", len, host, service); else fprintf (stderr, "getaddrnameinfo: %s\n", gai_strerror (s)); #endif // check the type of message received if (msg.type == REGISTRATION_MESSAGE) { // register the user if (!register_user (&msg, &client)) cerr << "Server: cannot register the user " << msg.from << endl; else cout << "Server: registered user " << msg.from << endl; } else if (msg.type == DEREGISTRATION_MESSAGE) { // deregister the user if (!deregister_user (&msg, &client)) cerr << "Server: cannot deregister the user " << msg.from << endl; else cout << "Server: deregistered user " << msg.from << endl; } else { // instant message if (!send_instant_msg (&msg, &client)) { cerr << "Server: cannot send message from " << msg.from; cerr << "to " << msg.to << endl; } else { cout << "Server: message sent from " << msg.from; cout << " to " << msg.to << endl; } } } } }
/* ** m_nick ** parv[0] = sender prefix ** parv[1] = nickname ** if from new client -taz ** parv[2] = nick password ** if from server: ** parv[2] = hopcount ** parv[3] = timestamp ** parv[4] = username ** parv[5] = hostname ** parv[6] = servername ** if NICK version 1: ** parv[7] = servicestamp ** parv[8] = info ** if NICK version 2: ** parv[7] = servicestamp ** parv[8] = umodes ** parv[9] = virthost, * if none ** parv[10] = info ** if NICKIP: ** parv[10] = ip ** parv[11] = info */ DLLFUNC CMD_FUNC(m_nick) { aTKline *tklban; int ishold; aClient *acptr, *serv = NULL; aClient *acptrs; char nick[NICKLEN + 2], *s; Membership *mp; time_t lastnick = (time_t) 0; int differ = 1, update_watch = 1; unsigned char newusr = 0, removemoder = 1; /* * If the user didn't specify a nickname, complain */ if (parc < 2) { sendto_one(sptr, err_str(ERR_NONICKNAMEGIVEN), me.name, parv[0]); return 0; } strncpyzt(nick, parv[1], NICKLEN + 1); if (MyConnect(sptr) && sptr->user && !IsAnOper(sptr)) { if ((sptr->user->flood.nick_c >= NICK_COUNT) && (TStime() - sptr->user->flood.nick_t < NICK_PERIOD)) { /* Throttle... */ sendto_one(sptr, err_str(ERR_NCHANGETOOFAST), me.name, sptr->name, nick, (int)(NICK_PERIOD - (TStime() - sptr->user->flood.nick_t))); return 0; } } /* For a local clients, do proper nickname checking via do_nick_name() * and reject the nick if it returns false. * For remote clients, do a quick check by using do_remote_nick_name(), * if this returned false then reject and kill it. -- Syzop */ if ((IsServer(cptr) && !do_remote_nick_name(nick)) || (!IsServer(cptr) && !do_nick_name(nick))) { sendto_one(sptr, err_str(ERR_ERRONEUSNICKNAME), me.name, parv[0], parv[1], "Illegal characters"); if (IsServer(cptr)) { ircstp->is_kill++; sendto_failops("Bad Nick: %s From: %s %s", parv[1], parv[0], get_client_name(cptr, FALSE)); sendto_one(cptr, ":%s KILL %s :%s (%s <- %s[%s])", me.name, parv[1], me.name, parv[1], nick, cptr->name); if (sptr != cptr) { /* bad nick change */ sendto_serv_butone(cptr, ":%s KILL %s :%s (%s <- %s!%s@%s)", me.name, parv[0], me.name, get_client_name(cptr, FALSE), parv[0], sptr->user ? sptr->username : "", sptr->user ? sptr->user->server : cptr->name); sptr->flags |= FLAGS_KILLED; return exit_client(cptr, sptr, &me, "BadNick"); } } return 0; } /* Kill quarantined opers early... */ if (IsServer(cptr) && (sptr->from->flags & FLAGS_QUARANTINE) && (parc >= 11) && strchr(parv[8], 'o')) { ircstp->is_kill++; /* Send kill to uplink only, hasn't been broadcasted to the rest, anyway */ sendto_one(cptr, ":%s KILL %s :%s (Quarantined: no global oper privileges allowed)", me.name, parv[1], me.name); sendto_realops("QUARANTINE: Oper %s on server %s killed, due to quarantine", parv[1], sptr->name); /* (nothing to exit_client or to free, since user was never added) */ return 0; } /* ** Protocol 4 doesn't send the server as prefix, so it is possible ** the server doesn't exist (a lagged net.burst), in which case ** we simply need to ignore the NICK. Also when we got that server ** name (again) but from another direction. --Run */ /* ** We should really only deal with this for msgs from servers. ** -- Aeto */ if (IsServer(cptr) && (parc > 7 && (!(serv = (aClient *)find_server_b64_or_real(parv[6])) || serv->from != cptr->from))) { sendto_realops("Cannot find server %s (%s)", parv[6], backupbuf); return 0; } /* ** Check against nick name collisions. ** ** Put this 'if' here so that the nesting goes nicely on the screen :) ** We check against server name list before determining if the nickname ** is present in the nicklist (due to the way the below for loop is ** constructed). -avalon */ /* I managed to f**k this up i guess --stskeeps */ if ((acptr = find_server(nick, NULL))) { if (MyConnect(sptr)) { #ifdef GUEST if (IsUnknown(sptr)) { RunHook4(HOOKTYPE_GUEST, cptr, sptr, parc, parv); return 0; } #endif sendto_one(sptr, err_str(ERR_NICKNAMEINUSE), me.name, BadPtr(parv[0]) ? "*" : parv[0], nick); return 0; /* NICK message ignored */ } } /* ** Check for a Q-lined nickname. If we find it, and it's our ** client, just reject it. -Lefler ** Allow opers to use Q-lined nicknames. -Russell */ if (!stricmp("ircd", nick)) { sendto_one(sptr, err_str(ERR_ERRONEUSNICKNAME), me.name, BadPtr(parv[0]) ? "*" : parv[0], nick, "Reserved for internal IRCd purposes"); return 0; } if (!stricmp("irc", nick)) { sendto_one(sptr, err_str(ERR_ERRONEUSNICKNAME), me.name, BadPtr(parv[0]) ? "*" : parv[0], nick, "Reserved for internal IRCd purposes"); return 0; } if (MyClient(sptr)) /* local client changin nick afterwards.. */ { int xx; spamfilter_build_user_string(spamfilter_user, nick, sptr); xx = dospamfilter(sptr, spamfilter_user, SPAMF_USER, NULL, 0, NULL); if (xx < 0) return xx; } if (!IsULine(sptr) && (tklban = find_qline(sptr, nick, &ishold))) { if (IsServer(sptr) && !ishold) /* server introducing new client */ { acptrs = (aClient *)find_server_b64_or_real(sptr->user == NULL ? (char *)parv[6] : (char *)sptr->user-> server); /* (NEW: no unregistered q:line msgs anymore during linking) */ if (!acptrs || (acptrs->serv && acptrs->serv->flags.synced)) sendto_snomask(SNO_QLINE, "Q:lined nick %s from %s on %s", nick, (*sptr->name != 0 && !IsServer(sptr) ? sptr->name : "<unregistered>"), acptrs ? acptrs->name : "unknown server"); } if (IsServer(cptr) && IsPerson(sptr) && !ishold) /* remote user changing nick */ { sendto_snomask(SNO_QLINE, "Q:lined nick %s from %s on %s", nick, sptr->name, sptr->srvptr ? sptr->srvptr->name : "<unknown>"); } if (!IsServer(cptr)) /* local */ { if (ishold) { sendto_one(sptr, err_str(ERR_ERRONEUSNICKNAME), me.name, BadPtr(parv[0]) ? "*" : parv[0], nick, tklban->reason); return 0; } if (!IsOper(cptr)) { sptr->since += 4; /* lag them up */ sendto_one(sptr, err_str(ERR_ERRONEUSNICKNAME), me.name, BadPtr(parv[0]) ? "*" : parv[0], nick, tklban->reason); sendto_snomask(SNO_QLINE, "Forbidding Q-lined nick %s from %s.", nick, get_client_name(cptr, FALSE)); return 0; /* NICK message ignored */ } } } /* ** acptr already has result from previous find_server() */ if (acptr) { /* ** We have a nickname trying to use the same name as ** a server. Send out a nick collision KILL to remove ** the nickname. As long as only a KILL is sent out, ** there is no danger of the server being disconnected. ** Ultimate way to jupiter a nick ? >;-). -avalon */ sendto_failops("Nick collision on %s(%s <- %s)", sptr->name, acptr->from->name, get_client_name(cptr, FALSE)); ircstp->is_kill++; sendto_one(cptr, ":%s KILL %s :%s (%s <- %s)", me.name, sptr->name, me.name, acptr->from->name, /* NOTE: Cannot use get_client_name ** twice here, it returns static ** string pointer--the other info ** would be lost */ get_client_name(cptr, FALSE)); sptr->flags |= FLAGS_KILLED; return exit_client(cptr, sptr, &me, "Nick/Server collision"); } if (MyClient(cptr) && !IsOper(cptr)) cptr->since += 3; /* Nick-flood prot. -Donwulff */ if (!(acptr = find_client(nick, NULL))) goto nickkilldone; /* No collisions, all clear... */ /* ** If the older one is "non-person", the new entry is just ** allowed to overwrite it. Just silently drop non-person, ** and proceed with the nick. This should take care of the ** "dormant nick" way of generating collisions... */ /* Moved before Lost User Field to fix some bugs... -- Barubary */ if (IsUnknown(acptr) && MyConnect(acptr)) { /* This may help - copying code below */ if (acptr == cptr) return 0; acptr->flags |= FLAGS_KILLED; exit_client(NULL, acptr, &me, "Overridden"); goto nickkilldone; } /* A sanity check in the user field... */ if (acptr->user == NULL) { /* This is a Bad Thing */ sendto_failops("Lost user field for %s in change from %s", acptr->name, get_client_name(cptr, FALSE)); ircstp->is_kill++; sendto_one(acptr, ":%s KILL %s :%s (Lost user field!)", me.name, acptr->name, me.name); acptr->flags |= FLAGS_KILLED; /* Here's the previous versions' desynch. If the old one is messed up, trash the old one and accept the new one. Remember - at this point there is a new nick coming in! Handle appropriately. -- Barubary */ exit_client(NULL, acptr, &me, "Lost user field"); goto nickkilldone; } /* ** If acptr == sptr, then we have a client doing a nick ** change between *equivalent* nicknames as far as server ** is concerned (user is changing the case of his/her ** nickname or somesuch) */ if (acptr == sptr) { if (strcmp(acptr->name, nick) != 0) { /* Allows change of case in his/her nick */ removemoder = 0; /* don't set the user -r */ goto nickkilldone; /* -- go and process change */ } else /* ** This is just ':old NICK old' type thing. ** Just forget the whole thing here. There is ** no point forwarding it to anywhere, ** especially since servers prior to this ** version would treat it as nick collision. */ return 0; /* NICK Message ignored */ } /* ** Note: From this point forward it can be assumed that ** acptr != sptr (point to different client structures). */ /* ** Decide, we really have a nick collision and deal with it */ if (!IsServer(cptr)) { /* ** NICK is coming from local client connection. Just ** send error reply and ignore the command. */ #ifdef GUEST if (IsUnknown(sptr)) { RunHook4(HOOKTYPE_GUEST, cptr, sptr, parc, parv); return 0; } #endif sendto_one(sptr, err_str(ERR_NICKNAMEINUSE), /* parv[0] is empty when connecting */ me.name, BadPtr(parv[0]) ? "*" : parv[0], nick); return 0; /* NICK message ignored */ } /* ** NICK was coming from a server connection. ** This means we have a race condition (two users signing on ** at the same time), or two net fragments reconnecting with ** the same nick. ** The latter can happen because two different users connected ** or because one and the same user switched server during a ** net break. ** If we have the old protocol (no TimeStamp and no user@host) ** or if the TimeStamps are equal, we kill both (or only 'new' ** if it was a "NICK new"). Otherwise we kill the youngest ** when user@host differ, or the oldest when they are the same. ** --Run ** */ if (IsServer(sptr)) { /* ** A new NICK being introduced by a neighbouring ** server (e.g. message type "NICK new" received) */ if (parc > 3) { lastnick = TS2ts(parv[3]); if (parc > 5) differ = (mycmp(acptr->user->username, parv[4]) || mycmp(acptr->user->realhost, parv[5])); } sendto_failops("Nick collision on %s (%s %ld <- %s %ld)", acptr->name, acptr->from->name, acptr->lastnick, cptr->name, lastnick); /* ** I'm putting the KILL handling here just to make it easier ** to read, it's hard to follow it the way it used to be. ** Basically, this is what it will do. It will kill both ** users if no timestamp is given, or they are equal. It will ** kill the user on our side if the other server is "correct" ** (user@host differ and their user is older, or user@host are ** the same and their user is younger), otherwise just kill the ** user an reintroduce our correct user. ** The old code just sat there and "hoped" the other server ** would kill their user. Not anymore. ** -- binary */ if (!(parc > 3) || (acptr->lastnick == lastnick)) { ircstp->is_kill++; sendto_serv_butone(NULL, ":%s KILL %s :%s (Nick Collision)", me.name, acptr->name, me.name); acptr->flags |= FLAGS_KILLED; (void)exit_client(NULL, acptr, &me, "Nick collision with no timestamp/equal timestamps"); return 0; /* We killed both users, now stop the process. */ } if ((differ && (acptr->lastnick > lastnick)) || (!differ && (acptr->lastnick < lastnick)) || acptr->from == cptr) /* we missed a QUIT somewhere ? */ { ircstp->is_kill++; sendto_serv_butone(cptr, ":%s KILL %s :%s (Nick Collision)", me.name, acptr->name, me.name); acptr->flags |= FLAGS_KILLED; (void)exit_client(NULL, acptr, &me, "Nick collision"); goto nickkilldone; /* OK, we got rid of the "wrong" user, ** now we're going to add the user the ** other server introduced. */ } if ((differ && (acptr->lastnick < lastnick)) || (!differ && (acptr->lastnick > lastnick))) { /* * Introduce our "correct" user to the other server */ sendto_one(cptr, ":%s KILL %s :%s (Nick Collision)", me.name, parv[1], me.name); send_umode(NULL, acptr, 0, SEND_UMODES, buf); sendto_one_nickcmd(cptr, acptr, buf); if (acptr->user->away) sendto_one(cptr, ":%s AWAY :%s", acptr->name, acptr->user->away); send_user_joins(cptr, acptr); return 0; /* Ignore the NICK */ } return 0; } else { /* ** A NICK change has collided (e.g. message type ":old NICK new"). */ if (parc > 2) lastnick = TS2ts(parv[2]); differ = (mycmp(acptr->user->username, sptr->user->username) || mycmp(acptr->user->realhost, sptr->user->realhost)); sendto_failops ("Nick change collision from %s to %s (%s %ld <- %s %ld)", sptr->name, acptr->name, acptr->from->name, acptr->lastnick, sptr->from->name, lastnick); if (!(parc > 2) || lastnick == acptr->lastnick) { ircstp->is_kill += 2; sendto_serv_butone(NULL, /* First kill the new nick. */ ":%s KILL %s :%s (Self Collision)", me.name, acptr->name, me.name); sendto_serv_butone(cptr, /* Tell my servers to kill the old */ ":%s KILL %s :%s (Self Collision)", me.name, sptr->name, me.name); sptr->flags |= FLAGS_KILLED; acptr->flags |= FLAGS_KILLED; (void)exit_client(NULL, sptr, &me, "Self Collision"); (void)exit_client(NULL, acptr, &me, "Self Collision"); return 0; /* Now that I killed them both, ignore the NICK */ } if ((differ && (acptr->lastnick > lastnick)) || (!differ && (acptr->lastnick < lastnick))) { /* sptr (their user) won, let's kill acptr (our user) */ ircstp->is_kill++; sendto_serv_butone(cptr, ":%s KILL %s :%s (Nick collision: %s <- %s)", me.name, acptr->name, me.name, acptr->from->name, sptr->from->name); acptr->flags |= FLAGS_KILLED; (void)exit_client(NULL, acptr, &me, "Nick collision"); goto nickkilldone; /* their user won, introduce new nick */ } if ((differ && (acptr->lastnick < lastnick)) || (!differ && (acptr->lastnick > lastnick))) { /* acptr (our user) won, let's kill sptr (their user), ** and reintroduce our "correct" user */ ircstp->is_kill++; /* Kill the user trying to change their nick. */ sendto_serv_butone(cptr, ":%s KILL %s :%s (Nick collision: %s <- %s)", me.name, sptr->name, me.name, sptr->from->name, acptr->from->name); sptr->flags |= FLAGS_KILLED; (void)exit_client(NULL, sptr, &me, "Nick collision"); /* * Introduce our "correct" user to the other server */ /* Kill their user. */ sendto_one(cptr, ":%s KILL %s :%s (Nick Collision)", me.name, parv[1], me.name); send_umode(NULL, acptr, 0, SEND_UMODES, buf); sendto_one_nickcmd(cptr, acptr, buf); if (acptr->user->away) sendto_one(cptr, ":%s AWAY :%s", acptr->name, acptr->user->away); send_user_joins(cptr, acptr); return 0; /* their user lost, ignore the NICK */ } } return 0; /* just in case */ nickkilldone: if (IsServer(sptr)) { /* A server introducing a new client, change source */ sptr = make_client(cptr, serv); add_client_to_list(sptr); if (parc > 2) sptr->hopcount = TS2ts(parv[2]); if (parc > 3) sptr->lastnick = TS2ts(parv[3]); else /* Little bit better, as long as not all upgraded */ sptr->lastnick = TStime(); if (sptr->lastnick < 0) { sendto_realops ("Negative timestamp recieved from %s, resetting to TStime (%s)", cptr->name, backupbuf); sptr->lastnick = TStime(); } newusr = 1; } else if (sptr->name[0] && IsPerson(sptr)) { /* ** If the client belongs to me, then check to see ** if client is currently on any channels where it ** is currently banned. If so, do not allow the nick ** change to occur. ** Also set 'lastnick' to current time, if changed. */ if (MyClient(sptr)) { for (mp = sptr->user->channel; mp; mp = mp->next) { if (!is_skochanop(sptr, mp->chptr) && is_banned(sptr, mp->chptr, BANCHK_NICK)) { sendto_one(sptr, err_str(ERR_BANNICKCHANGE), me.name, parv[0], mp->chptr->chname); return 0; } if (CHECK_TARGET_NICK_BANS && !is_skochanop(sptr, mp->chptr) && is_banned_with_nick(sptr, mp->chptr, BANCHK_NICK, nick)) { sendto_one(sptr, ":%s 437 %s %s :Cannot change to a nickname banned on channel", me.name, parv[0], mp->chptr->chname); return 0; } if (!IsOper(sptr) && !IsULine(sptr) && mp->chptr->mode.mode & MODE_NONICKCHANGE && !is_chanownprotop(sptr, mp->chptr)) { sendto_one(sptr, err_str(ERR_NONICKCHANGE), me.name, parv[0], mp->chptr->chname); return 0; } } if (TStime() - sptr->user->flood.nick_t >= NICK_PERIOD) { sptr->user->flood.nick_t = TStime(); sptr->user->flood.nick_c = 1; } else sptr->user->flood.nick_c++; sendto_snomask(SNO_NICKCHANGE, "*** Notice -- %s (%s@%s) has changed his/her nickname to %s", sptr->name, sptr->user->username, sptr->user->realhost, nick); RunHook2(HOOKTYPE_LOCAL_NICKCHANGE, sptr, nick); } else { if (!IsULine(sptr)) sendto_snomask(SNO_FNICKCHANGE, "*** Notice -- %s (%s@%s) has changed his/her nickname to %s", sptr->name, sptr->user->username, sptr->user->realhost, nick); RunHook3(HOOKTYPE_REMOTE_NICKCHANGE, cptr, sptr, nick); } /* * Client just changing his/her nick. If he/she is * on a channel, send note of change to all clients * on that channel. Propagate notice to other servers. */ if (mycmp(parv[0], nick) || /* Next line can be removed when all upgraded --Run */ (!MyClient(sptr) && parc > 2 && TS2ts(parv[2]) < sptr->lastnick)) sptr->lastnick = (MyClient(sptr) || parc < 3) ? TStime() : TS2ts(parv[2]); if (sptr->lastnick < 0) { sendto_realops("Negative timestamp (%s)", backupbuf); sptr->lastnick = TStime(); } add_history(sptr, 1); sendto_common_channels(sptr, ":%s NICK :%s", parv[0], nick); sendto_serv_butone_token(cptr, parv[0], MSG_NICK, TOK_NICK, "%s %ld", nick, sptr->lastnick); if (removemoder) sptr->umodes &= ~UMODE_REGNICK; } else if (!sptr->name[0]) { #ifdef NOSPOOF /* * Client setting NICK the first time. * * Generate a random string for them to pong with. */ sptr->nospoof = getrandom32(); if (PINGPONG_WARNING) sendto_one(sptr, ":%s NOTICE %s :*** If you are having problems" " connecting due to ping timeouts, please" " type /quote pong %X or /raw pong %X now.", me.name, nick, sptr->nospoof, sptr->nospoof); sendto_one(sptr, "PING :%X", sptr->nospoof); #endif /* NOSPOOF */ #ifdef CONTACT_EMAIL sendto_one(sptr, ":%s NOTICE %s :*** If you need assistance with a" " connection problem, please email " CONTACT_EMAIL " with the name and version of the client you are" " using, and the server you tried to connect to: %s", me.name, nick, me.name); #endif /* CONTACT_EMAIL */ #ifdef CONTACT_URL sendto_one(sptr, ":%s NOTICE %s :*** If you need assistance with" " connecting to this server, %s, please refer to: " CONTACT_URL, me.name, nick, me.name); #endif /* CONTACT_URL */ /* Copy password to the passwd field if it's given after NICK * - originally by taz, modified by Wizzu */ if ((parc > 2) && (strlen(parv[2]) <= PASSWDLEN) && !(sptr->listener->umodes & LISTENER_JAVACLIENT)) { if (sptr->passwd) MyFree(sptr->passwd); sptr->passwd = MyMalloc(strlen(parv[2]) + 1); (void)strcpy(sptr->passwd, parv[2]); } /* This had to be copied here to avoid problems.. */ (void)strcpy(sptr->name, nick); if (sptr->user && IsNotSpoof(sptr)) { /* ** USER already received, now we have NICK. ** *NOTE* For servers "NICK" *must* precede the ** user message (giving USER before NICK is possible ** only for local client connection!). register_user ** may reject the client and call exit_client for it ** --must test this and exit m_nick too!!! */ #ifndef NOSPOOF if (USE_BAN_VERSION && MyConnect(sptr)) sendto_one(sptr, ":IRC!IRC@%s PRIVMSG %s :\1VERSION\1", me.name, nick); #endif sptr->lastnick = TStime(); /* Always local client */ if (register_user(cptr, sptr, nick, sptr->user->username, NULL, NULL, NULL) == FLUSH_BUFFER) return FLUSH_BUFFER; strcpy(nick, sptr->name); /* don't ask, but I need this. do not remove! -- Syzop */ update_watch = 0; newusr = 1; } } /* * Finally set new nick name. */ if (update_watch && sptr->name[0]) { (void)del_from_client_hash_table(sptr->name, sptr); if (IsPerson(sptr)) hash_check_watch(sptr, RPL_LOGOFF); } (void)strcpy(sptr->name, nick); (void)add_to_client_hash_table(nick, sptr); if (IsServer(cptr) && parc > 7) { parv[3] = nick; do_cmd(cptr, sptr, "USER", parc - 3, &parv[3]); if (GotNetInfo(cptr) && !IsULine(sptr)) sendto_fconnectnotice(sptr->name, sptr->user, sptr, 0, NULL); } else if (IsPerson(sptr) && update_watch) hash_check_watch(sptr, RPL_LOGON); #ifdef NEWCHFLOODPROT if (sptr->user && !newusr && !IsULine(sptr)) { for (mp = sptr->user->channel; mp; mp = mp->next) { aChannel *chptr = mp->chptr; if (chptr && !(mp->flags & (CHFL_CHANOP|CHFL_VOICE|CHFL_CHANOWNER|CHFL_HALFOP|CHFL_CHANPROT)) && chptr->mode.floodprot && do_chanflood(chptr->mode.floodprot, FLD_NICK) && MyClient(sptr)) { do_chanflood_action(chptr, FLD_NICK, "nick"); } } } #endif if (newusr && !MyClient(sptr) && IsPerson(sptr)) { RunHook(HOOKTYPE_REMOTE_CONNECT, sptr); } return 0; }
/* ** m_user ** parv[0] = sender prefix ** parv[1] = username (login name, account) ** parv[2] = client host name (used only from other servers) ** parv[3] = server host name (used only from other servers) ** parv[4] = users real name info ** ** NOTE: Be advised that multiple USER messages are possible, ** hence, always check if a certain struct is already allocated... -- Syzop */ DLLFUNC CMD_FUNC(m_user) { #define UFLAGS (UMODE_INVISIBLE|UMODE_WALLOP|UMODE_SERVNOTICE) char *username, *host, *server, *realname, *umodex = NULL, *virthost = NULL, *ip = NULL; u_int32_t sstamp = 0; anUser *user; aClient *acptr; if (IsServer(cptr) && !IsUnknown(sptr)) return 0; if (MyConnect(sptr) && (sptr->listener->umodes & LISTENER_SERVERSONLY)) { return exit_client(cptr, sptr, sptr, "This port is for servers only"); } if (parc > 2 && (username = (char *)index(parv[1], '@'))) *username = '******'; if (parc < 5 || *parv[1] == '\0' || *parv[2] == '\0' || *parv[3] == '\0' || *parv[4] == '\0') { sendto_one(sptr, err_str(ERR_NEEDMOREPARAMS), me.name, parv[0], "USER"); if (IsServer(cptr)) sendto_ops("bad USER param count for %s from %s", parv[0], get_client_name(cptr, FALSE)); else return 0; } /* Copy parameters into better documenting variables */ username = (parc < 2 || BadPtr(parv[1])) ? "<bad-boy>" : parv[1]; host = (parc < 3 || BadPtr(parv[2])) ? "<nohost>" : parv[2]; server = (parc < 4 || BadPtr(parv[3])) ? "<noserver>" : parv[3]; /* This we can remove as soon as all servers have upgraded. */ if (parc == 6 && IsServer(cptr)) { if (isdigit(*parv[4])) sstamp = strtoul(parv[4], NULL, 10); realname = (BadPtr(parv[5])) ? "<bad-realname>" : parv[5]; umodex = NULL; } else if (parc == 8 && IsServer(cptr)) { if (isdigit(*parv[4])) sstamp = strtoul(parv[4], NULL, 10); realname = (BadPtr(parv[7])) ? "<bad-realname>" : parv[7]; umodex = parv[5]; virthost = parv[6]; } else if (parc == 9 && IsServer(cptr)) { if (isdigit(*parv[4])) sstamp = strtoul(parv[4], NULL, 10); realname = (BadPtr(parv[8])) ? "<bad-realname>" : parv[8]; umodex = parv[5]; virthost = parv[6]; ip = parv[7]; } else { realname = (BadPtr(parv[4])) ? "<bad-realname>" : parv[4]; } user = make_user(sptr); if (!MyConnect(sptr)) { if (sptr->srvptr == NULL) sendto_ops("WARNING, User %s introduced as being " "on non-existant server %s.", sptr->name, server); if (SupportNS(cptr)) { acptr = (aClient *)find_server_b64_or_real(server); if (acptr) user->server = find_or_add(acptr->name); else user->server = find_or_add(server); } else user->server = find_or_add(server); strlcpy(user->realhost, host, sizeof(user->realhost)); goto user_finish; } if (!IsUnknown(sptr)) { sendto_one(sptr, err_str(ERR_ALREADYREGISTRED), me.name, parv[0]); return 0; } if (!IsServer(cptr)) { sptr->umodes |= CONN_MODES; if (CONNECT_SNOMASK) { sptr->umodes |= UMODE_SERVNOTICE; create_snomask(sptr, user, CONNECT_SNOMASK); } } /* Set it temporarely to at least something trusted, * this was copying user supplied data directly into user->realhost * which seemed bad. Not to say this is much better ;p. -- Syzop */ strncpyzt(user->realhost, Inet_ia2p(&sptr->ip), sizeof(user->realhost)); if (!user->ip_str) user->ip_str = strdup(Inet_ia2p(&sptr->ip)); user->server = me_hash; user_finish: user->servicestamp = sstamp; strlcpy(sptr->info, realname, sizeof(sptr->info)); if (sptr->name[0] && (IsServer(cptr) ? 1 : IsNotSpoof(sptr))) /* NICK and no-spoof already received, now we have USER... */ { if (USE_BAN_VERSION && MyConnect(sptr)) sendto_one(sptr, ":IRC!IRC@%s PRIVMSG %s :\1VERSION\1", me.name, sptr->name); if (strlen(username) > USERLEN) username[USERLEN] = '\0'; /* cut-off */ return( register_user(cptr, sptr, sptr->name, username, umodex, virthost,ip)); } else strncpyzt(sptr->user->username, username, USERLEN + 1); return 0; }