00001
00002
00003
00004
00005
00006 #include "copyright.h"
00007 #include "config.h"
00008
00009 #include "mudconf.h"
00010 #include "config.h"
00011 #include "db.h"
00012 #include "interface.h"
00013 #include "externs.h"
00014 #include "alloc.h"
00015 #include "attrs.h"
00016 #include "powers.h"
00017 #include "command.h"
00018
00019 #define NUM_GOOD 4
00020
00021
00022 #define NUM_BAD 3
00023
00024
00025
00026 typedef struct hostdtm HOSTDTM;
00027 struct hostdtm {
00028 char *host;
00029 char *dtm;
00030 };
00031
00032 typedef struct logindata LDATA;
00033 struct logindata {
00034 HOSTDTM good[NUM_GOOD];
00035 HOSTDTM bad[NUM_BAD];
00036 int tot_good;
00037 int tot_bad;
00038 int new_bad;
00039 };
00040
00041 extern char *crypt(const char *, const char *);
00042 extern time_t time(time_t *);
00043
00047 static void decrypt_logindata(char *atrbuf, LDATA * info)
00048 {
00049 int i;
00050 char *tmpc;
00051
00052 info->tot_good = 0;
00053 info->tot_bad = 0;
00054 info->new_bad = 0;
00055 for(i = 0; i < NUM_GOOD; i++) {
00056 info->good[i].host = NULL;
00057 info->good[i].dtm = NULL;
00058 }
00059 for(i = 0; i < NUM_BAD; i++) {
00060 info->bad[i].host = NULL;
00061 info->bad[i].dtm = NULL;
00062 }
00063
00064 if(*atrbuf == '#') {
00065 atrbuf++;
00066 if(!(tmpc = grabto(&atrbuf, ';')))
00067 return;
00068 info->tot_good = atoi(tmpc);
00069 for(i = 0; i < NUM_GOOD; i++) {
00070 if(!(tmpc = grabto(&atrbuf, ';')))
00071 return;
00072 info->good[i].host = tmpc;
00073 if(!(tmpc = grabto(&atrbuf, ';')))
00074 return;
00075 info->good[i].dtm = tmpc;
00076 }
00077 if(!(tmpc = grabto(&atrbuf, ';')))
00078 return;
00079 info->new_bad = atoi(tmpc);
00080 if(!(tmpc = grabto(&atrbuf, ';')))
00081 return;
00082 info->tot_bad = atoi(tmpc);
00083 for(i = 0; i < NUM_BAD; i++) {
00084 if(!(tmpc = grabto(&atrbuf, ';')))
00085 return;
00086 info->bad[i].host = tmpc;
00087 if(!(tmpc = grabto(&atrbuf, ';')))
00088 return;
00089 info->bad[i].dtm = tmpc;
00090 }
00091 }
00092 }
00093
00097 static void encrypt_logindata(char *atrbuf, LDATA * info)
00098 {
00099 char *bp, nullc;
00100 int i;
00101
00102
00103
00104
00105
00106
00107
00108 nullc = '\0';
00109 for(i = 0; i < NUM_GOOD; i++) {
00110 if(!info->good[i].host)
00111 info->good[i].host = &nullc;
00112 if(!info->good[i].dtm)
00113 info->good[i].dtm = &nullc;
00114 }
00115 for(i = 0; i < NUM_BAD; i++) {
00116 if(!info->bad[i].host)
00117 info->bad[i].host = &nullc;
00118 if(!info->bad[i].dtm)
00119 info->bad[i].dtm = &nullc;
00120 }
00121 bp = alloc_lbuf("encrypt_logindata");
00122 sprintf(bp, "#%d;%s;%s;%s;%s;%s;%s;%s;%s;%d;%d;%s;%s;%s;%s;%s;%s;",
00123 info->tot_good, info->good[0].host, info->good[0].dtm,
00124 info->good[1].host, info->good[1].dtm, info->good[2].host,
00125 info->good[2].dtm, info->good[3].host, info->good[3].dtm,
00126 info->new_bad, info->tot_bad, info->bad[0].host, info->bad[0].dtm,
00127 info->bad[1].host, info->bad[1].dtm, info->bad[2].host,
00128 info->bad[2].dtm);
00129 StringCopy(atrbuf, bp);
00130 free_lbuf(bp);
00131 }
00132
00138 void record_login(dbref player, int isgood, char *ldate, char *lhost,
00139 char *lusername)
00140 {
00141 LDATA login_info;
00142 char *atrbuf;
00143 dbref aowner;
00144 int aflags, i;
00145
00146 atrbuf = atr_get(player, A_LOGINDATA, &aowner, &aflags);
00147 decrypt_logindata(atrbuf, &login_info);
00148 if(isgood) {
00149 if(login_info.new_bad > 0) {
00150 notify(player, "");
00151 notify_printf(player,
00152 "**** %d failed connect%s since your last successful connect. ****",
00153 login_info.new_bad,
00154 (login_info.new_bad == 1 ? "" : "s"));
00155 notify_printf(player,
00156 "Most recent attempt was from %s on %s.",
00157 login_info.bad[0].host, login_info.bad[0].dtm);
00158 notify(player, "");
00159 login_info.new_bad = 0;
00160 }
00161 if(login_info.good[0].host && *login_info.good[0].host &&
00162 login_info.good[0].dtm && *login_info.good[0].dtm) {
00163 notify_printf(player, "Last connect was from %s on %s.",
00164 login_info.good[0].host, login_info.good[0].dtm);
00165 }
00166 if(mudconf.have_mailer)
00167 check_mail(player, 0, 0);
00168 for(i = NUM_GOOD - 1; i > 0; i--) {
00169 login_info.good[i].dtm = login_info.good[i - 1].dtm;
00170 login_info.good[i].host = login_info.good[i - 1].host;
00171 }
00172 login_info.good[0].dtm = ldate;
00173 login_info.good[0].host = lhost;
00174 login_info.tot_good++;
00175 if(*lusername)
00176 atr_add_raw(player, A_LASTSITE, tprintf("%s@%s", lusername,
00177 lhost));
00178 else
00179 atr_add_raw(player, A_LASTSITE, lhost);
00180 } else {
00181 for(i = NUM_BAD - 1; i > 0; i--) {
00182 login_info.bad[i].dtm = login_info.bad[i - 1].dtm;
00183 login_info.bad[i].host = login_info.bad[i - 1].host;
00184 }
00185 login_info.bad[0].dtm = ldate;
00186 login_info.bad[0].host = lhost;
00187 login_info.tot_bad++;
00188 login_info.new_bad++;
00189 }
00190 encrypt_logindata(atrbuf, &login_info);
00191 atr_add_raw(player, A_LOGINDATA, atrbuf);
00192 free_lbuf(atrbuf);
00193 }
00194
00198 int check_pass(dbref player, const char *password)
00199 {
00200 dbref aowner;
00201 int aflags;
00202 char *target;
00203 char *hashed;
00204
00205 target = atr_get(player, A_PASS, &aowner, &aflags);
00206 hashed = crypt(password, "XX");
00207 if(*target && strcmp(target, password) && strcmp(hashed, target)) {
00208 free_lbuf(target);
00209 return 0;
00210 }
00211 free_lbuf(target);
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221 if((strlen(password) == 13) && (password[0] == 'X') &&
00222 (password[1] == 'X'))
00223 return 0;
00224
00225 return 1;
00226 }
00227
00231 dbref connect_player(char *name, char *password, char *host, char *username)
00232 {
00233 dbref player, aowner;
00234 int aflags;
00235 time_t tt;
00236 char *time_str, *player_last, *allowance;
00237
00238 time(&tt);
00239 time_str = ctime(&tt);
00240 time_str[strlen(time_str) - 1] = '\0';
00241
00242 if((player = lookup_player(NOTHING, name, 0)) == NOTHING)
00243 return NOTHING;
00244 if(!check_pass(player, password)) {
00245 record_login(player, 0, time_str, host, username);
00246 return NOTHING;
00247 }
00248 time(&tt);
00249 time_str = ctime(&tt);
00250 time_str[strlen(time_str) - 1] = '\0';
00251
00252
00253
00254
00255 player_last = atr_get(player, A_LAST, &aowner, &aflags);
00256 if(strncmp(player_last, time_str, 10) != 0) {
00257 allowance = atr_pget(player, A_ALLOWANCE, &aowner, &aflags);
00258 if(*allowance == '\0')
00259 giveto(player, mudconf.paycheck);
00260 else
00261 giveto(player, atoi(allowance));
00262 free_lbuf(allowance);
00263 }
00264 atr_add_raw(player, A_LAST, time_str);
00265 free_lbuf(player_last);
00266 return player;
00267 }
00268
00272 dbref create_player(char *name, char *password, dbref creator, int isrobot,
00273 int isguest)
00274 {
00275 dbref player;
00276 char *pbuf;
00277
00278
00279
00280
00281
00282 pbuf = trim_spaces(password);
00283 if(!ok_password(pbuf)) {
00284 free_lbuf(pbuf);
00285 return NOTHING;
00286 }
00287
00288
00289
00290
00291 player = create_obj(creator, TYPE_PLAYER, name, isrobot);
00292 if(player == NOTHING) {
00293 free_lbuf(pbuf);
00294 return NOTHING;
00295 }
00296
00297
00298
00299 if(isguest) {
00300 if(*mudconf.guests_channel)
00301 do_addcom(player, player, 0, "g", mudconf.guests_channel);
00302 } else {
00303 if(*mudconf.public_channel)
00304 do_addcom(player, player, 0, "pub", mudconf.public_channel);
00305 }
00306
00307 s_Pass(player, crypt(pbuf, "XX"));
00308 s_Home(player, start_home());
00309 s_Fixed(player);
00310 free_lbuf(pbuf);
00311 return player;
00312 }
00313
00317 void do_password(dbref player, dbref cause, int key, char *oldpass,
00318 char *newpass)
00319 {
00320 dbref aowner;
00321 int aflags;
00322 char *target;
00323
00324 target = atr_get(player, A_PASS, &aowner, &aflags);
00325 if(!*target || !check_pass(player, oldpass)) {
00326 notify(player, "Sorry.");
00327 } else if(!ok_password(newpass)) {
00328 notify(player, "Bad new password.");
00329 } else {
00330 atr_add_raw(player, A_PASS, crypt(newpass, "XX"));
00331 notify(player, "Password changed.");
00332 }
00333 free_lbuf(target);
00334 }
00335
00339 static void disp_from_on(dbref player, char *dtm_str, char *host_str)
00340 {
00341 if(dtm_str && *dtm_str && host_str && *host_str) {
00342 notify_printf(player, " From: %s On: %s", dtm_str, host_str);
00343 }
00344 }
00345
00346 void do_last(dbref player, dbref cause, int key, char *who)
00347 {
00348 dbref target, aowner;
00349 LDATA login_info;
00350 char *atrbuf;
00351 int i, aflags;
00352
00353 if(!who || !*who) {
00354 target = Owner(player);
00355 } else if(!(string_compare(who, "me"))) {
00356 target = Owner(player);
00357 } else {
00358 target = lookup_player(player, who, 1);
00359 }
00360
00361 if(target == NOTHING) {
00362 notify(player, "I couldn't find that player.");
00363 } else if(!Controls(player, target)) {
00364 notify(player, "Permission denied.");
00365 } else {
00366 atrbuf = atr_get(target, A_LOGINDATA, &aowner, &aflags);
00367 decrypt_logindata(atrbuf, &login_info);
00368
00369 notify_printf(player, "Total successful connects: %d",
00370 login_info.tot_good);
00371 for(i = 0; i < NUM_GOOD; i++) {
00372 disp_from_on(player, login_info.good[i].host,
00373 login_info.good[i].dtm);
00374 }
00375 notify_printf(player, "Total failed connects: %d",
00376 login_info.tot_bad);
00377 for(i = 0; i < NUM_BAD; i++) {
00378 disp_from_on(player, login_info.bad[i].host,
00379 login_info.bad[i].dtm);
00380 }
00381 free_lbuf(atrbuf);
00382 }
00383 }
00384
00385
00386
00387
00388
00389 int add_player_name(dbref player, char *name)
00390 {
00391 int stat;
00392 dbref *p;
00393 char *temp, *tp;
00394
00395
00396
00397
00398
00399 tp = temp = alloc_lbuf("add_player_name");
00400 safe_str(name, temp, &tp);
00401 *tp = '\0';
00402 for(tp = temp; *tp; tp++)
00403 *tp = ToLower(*tp);
00404
00405 p = (int *) hashfind(temp, &mudstate.player_htab);
00406 if(p) {
00407
00408
00409
00410
00411
00412
00413
00414
00415 if(*p == AMBIGUOUS) {
00416 free_lbuf(temp);
00417 return 0;
00418 }
00419 if(Good_obj(*p) && (Typeof(*p) == TYPE_PLAYER)) {
00420 free_lbuf(temp);
00421 if(*p == player) {
00422 return 1;
00423 } else {
00424 return 0;
00425 }
00426 }
00427
00428
00429
00430 free(p);
00431 p = (dbref *) malloc(sizeof(int));
00432
00433 *p = player;
00434 stat = hashrepl(temp, p, &mudstate.player_htab);
00435 free_lbuf(temp);
00436 } else {
00437 p = (dbref *) malloc(sizeof(int));
00438
00439 *p = player;
00440 stat = hashadd(temp, p, &mudstate.player_htab);
00441 free_lbuf(temp);
00442 stat = (stat < 0) ? 0 : 1;
00443 }
00444 return stat;
00445 }
00446
00447 int delete_player_name(dbref player, char *name)
00448 {
00449 dbref *p;
00450 char *temp, *tp;
00451
00452 tp = temp = alloc_lbuf("delete_player_name");
00453 safe_str(name, temp, &tp);
00454 *tp = '\0';
00455 for(tp = temp; *tp; tp++)
00456 *tp = ToLower(*tp);
00457
00458 p = (int *) hashfind(temp, &mudstate.player_htab);
00459 if(!p || (*p == NOTHING) || ((player != NOTHING) && (*p != player))) {
00460 free_lbuf(temp);
00461 return 0;
00462 }
00463 free(p);
00464 hashdelete(temp, &mudstate.player_htab);
00465 free_lbuf(temp);
00466 return 1;
00467 }
00468
00469 dbref lookup_player(dbref doer, char *name, int check_who)
00470 {
00471 dbref *p, thing;
00472 char *temp, *tp;
00473
00474 if(!string_compare(name, "me"))
00475 return doer;
00476
00477 if(*name == NUMBER_TOKEN) {
00478 name++;
00479 if(!is_number(name))
00480 return NOTHING;
00481 thing = atoi(name);
00482 if(!Good_obj(thing))
00483 return NOTHING;
00484 if(!((Typeof(thing) == TYPE_PLAYER) || God(doer)))
00485 thing = NOTHING;
00486 return thing;
00487 }
00488 tp = temp = alloc_lbuf("lookup_player");
00489 safe_str(name, temp, &tp);
00490 *tp = '\0';
00491 for(tp = temp; *tp; tp++)
00492 *tp = ToLower(*tp);
00493 p = (int *) hashfind(temp, &mudstate.player_htab);
00494 free_lbuf(temp);
00495 if(!p) {
00496 if(check_who) {
00497 thing = find_connected_name(doer, name);
00498 if(Dark(thing))
00499 thing = NOTHING;
00500 } else
00501 thing = NOTHING;
00502 } else if(!Good_obj(*p)) {
00503 thing = NOTHING;
00504 } else
00505 thing = *p;
00506
00507 return thing;
00508 }
00509
00510 void load_player_names(void)
00511 {
00512 dbref i, j, aowner;
00513 int aflags;
00514 char *alias;
00515
00516 j = 0;
00517 DO_WHOLE_DB(i) {
00518 if(Typeof(i) == TYPE_PLAYER) {
00519 add_player_name(i, Name(i));
00520 }
00521 }
00522 alias = alloc_lbuf("load_player_names");
00523 j = 0;
00524 DO_WHOLE_DB(i) {
00525 if(Typeof(i) == TYPE_PLAYER) {
00526 alias = atr_pget_str(alias, i, A_ALIAS, &aowner, &aflags);
00527 if(*alias)
00528 add_player_name(i, alias);
00529 }
00530 }
00531 free_lbuf(alias);
00532 }
00533
00537 void badname_add(char *bad_name)
00538 {
00539 BADNAME *bp;
00540
00541
00542
00543
00544
00545 bp = (BADNAME *) XMALLOC(sizeof(BADNAME), "badname.struc");
00546 bp->name = XMALLOC(strlen(bad_name) + 1, "badname.name");
00547 bp->next = mudstate.badname_head;
00548 mudstate.badname_head = bp;
00549 StringCopy(bp->name, bad_name);
00550 }
00551
00552 void badname_remove(char *bad_name)
00553 {
00554 BADNAME *bp, *backp;
00555
00556
00557
00558
00559
00560 backp = NULL;
00561 for(bp = mudstate.badname_head; bp; backp = bp, bp = bp->next) {
00562 if(!string_compare(bad_name, bp->name)) {
00563 if(backp)
00564 backp->next = bp->next;
00565 else
00566 mudstate.badname_head = bp->next;
00567 XFREE(bp->name, "badname.name");
00568 XFREE(bp, "badname.struc");
00569 return;
00570 }
00571 }
00572 }
00573
00574 int badname_check(char *bad_name)
00575 {
00576 BADNAME *bp;
00577
00578
00579
00580
00581
00582
00583
00584
00585 for(bp = mudstate.badname_head; bp; bp = bp->next) {
00586 if(quick_wild(bp->name, bad_name))
00587 return 0;
00588 }
00589 return 1;
00590 }
00591
00592 void badname_list(dbref player, const char *prefix)
00593 {
00594 BADNAME *bp;
00595 char *buff, *bufp;
00596
00597
00598
00599
00600
00601 buff = bufp = alloc_lbuf("badname_list");
00602 safe_str((char *) prefix, buff, &bufp);
00603 for(bp = mudstate.badname_head; bp; bp = bp->next) {
00604 safe_chr(' ', buff, &bufp);
00605 safe_str(bp->name, buff, &bufp);
00606 }
00607 *bufp = '\0';
00608
00609
00610
00611
00612
00613 notify(player, buff);
00614 free_lbuf(buff);
00615 }