/***************************************************************************** * * File ..................: bbs/user.c * Purpose ...............: Main user login procedure. Checks for limits, * new ratio's cats all the welcome screens, and * does a lot of checking in general. * Last modification date : 27-Oct-2001 * ***************************************************************************** * Copyright (C) 1997-2001 * * Michiel Broek FIDO: 2:280/2802 * Beekmansbos 10 * 1971 BV IJmuiden * the Netherlands * * This file is part of MBSE BBS. * * This BBS is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2, or (at your option) any * later version. * * MBSE BBS is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with MBSE BBS; see the file COPYING. If not, write to the Free * Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. *****************************************************************************/ #include "../lib/libs.h" #include "../lib/mbse.h" #include "../lib/structs.h" #include "../lib/records.h" #include "../lib/common.h" #include "../lib/clcomm.h" #include "timeout.h" #include "user.h" #include "pwcheck.h" #include "funcs.h" #include "funcs4.h" #include "misc.h" #include "bye.h" #include "file.h" #include "mail.h" #include "change.h" #include "menu.h" #include "exitinfo.h" #include "language.h" #include "offline.h" #include "statetbl.h" #include "email.h" #include "newuser.h" extern int sock; extern pid_t mypid; char *StartTime; /* Non global function prototypes */ char *AskLogin(void); static int rxemsi(void); char *Passwd = NULL; int iMaxLogin = 1; char *ieUserName = NULL; char *ieHandle = NULL; char *ieLocation = NULL; char *ieVoicePhone = NULL; char *ieDataPhone = NULL; long iePassword = 0; char *ieBirthDate = NULL; char *ieTerminal = NULL; int ieRows = 0; int ieCols = 0; int ieNulls = 0; int ieDZA = FALSE; int ieZAP = FALSE; int ieZMO = FALSE; int ieSLK = FALSE; int ieKER = FALSE; int ieCHT = FALSE; int ieMNU = FALSE; int ieTAB = FALSE; int ieASCII8 = FALSE; int ieNEWS = FALSE; int ieMAIL = FALSE; int ieFILE = FALSE; int ieHOT = FALSE; int ieCLR = FALSE; int ieHUSH = FALSE; int ieMORE = FALSE; int ieFSED = FALSE; int ieXPRS = FALSE; char *ieSoftware = NULL; int ieLogin = FALSE; /* * Ask for BBS Login name (Firstname Lastname) and try to * establish an IEMSI session if the client supports it. */ char *AskLogin(void); char *AskLogin(void) { char temp[36]; int Count = 0, rc = 0; static char GetName[36]; do { /* * if after the first time IEMSI failed rc will not be * zero anymore so we don't check for IEMSI logon anymore. */ if (rc == 0) { rc = rxemsi(); if (rc) Syslog('+', "rxemsi rc=%d", rc); } if (rc) { /* * IEMSI Aborted or other errors, so prompt user. * Note that if the user didn't had an IEMSI client, * rc is still 0, the name is entered in the rxemsi * function. */ /* Please enter your First and Last name: */ language(7, 0, 0); fflush(stdout); alarm_on(); Getname(GetName, 35); } else { sprintf(GetName, "%s", ieUserName); } if ((strcmp(GetName,"")) == 0) { Count++; if (Count >= CFG.iCRLoginCount) { Enter(1); /* Disconnecting user ... */ language(CFG.HiliteF, CFG.HiliteB, 2); Enter(2); Syslog('!', "Exceeded maximum login attempts"); free(Passwd); Quick_Bye(0); } } } while (strcmp(GetName, "") == 0); strcpy(temp, GetName); /* * Secret escape name */ if ((strcasecmp(temp, "off")) == 0) { Syslog('+', "Quick \"off\" logout"); free(Passwd); Quick_Bye(0); } /* * Check for singlename */ if ((strchr(GetName,' ') == NULL && !CFG.iOneName)) { Syslog('+', "Did not enter a full name"); Count = -1; while (TRUE) { do { Count++; if (Count >= CFG.iCRLoginCount) { Enter(1); /* Disconnecting user ... */ language(CFG.HiliteF, CFG.HiliteB, 2); Enter(2); Syslog('!', "Exceeded maximum login attempts"); free(Passwd); Quick_Bye(0); } /* Please enter your Last name: */ language(LIGHTGRAY, BLACK, 1); fflush(stdout); alarm_on(); Getname(temp, 34 - strlen(GetName)); } while ((strcmp(temp, "")) == 0); if((strcmp(temp,"")) != 0) { strcat(GetName," "); strcat(GetName,temp); break; } } } alarm_off(); return GetName; } /* * The next function is "borrowed" from Eugene M. Crossers ifcico. */ char *sel_brace(char *); char *sel_brace(char *s) { static char *save; char *p, *q; int i; if (s == NULL) s = save; for (; *s && (*s != '{'); s++); if (*s == '\0') { save = s; return NULL; } else s++; for (p = s, q = s; *p; p++) switch(*p) { case '}': if (*(p+1) == '}') *q++ = *p++; else { *q = '\0'; save = p+1; goto exit; } break; case '\\': if (*(p+1) == '\\') *q++ = *p++; else { sscanf(p+1, "%02x", &i); *q++ = i; p+=2; } break; default: *q++ = *p; break; } exit: return s; } int scanemsiici(char *); int scanemsiici(char *buf) { char *p, *q; ieUserName = xstrcpy(sel_brace(buf)); Syslog('i', "Username : %s", MBSE_SS(ieUserName)); ieHandle = xstrcpy(sel_brace(NULL)); Syslog('i', "Handle : %s", MBSE_SS(ieHandle)); ieLocation = xstrcpy(sel_brace(NULL)); Syslog('i', "Location : %s", MBSE_SS(ieLocation)); ieVoicePhone = xstrcpy(sel_brace(NULL)); Syslog('i', "Voice Phone : %s", MBSE_SS(ieVoicePhone)); ieDataPhone = xstrcpy(sel_brace(NULL)); Syslog('i', "Data Phone : %s", MBSE_SS(ieDataPhone)); p = sel_brace(NULL); memset(Passwd, 0, 16); if (strlen(p) < 16) sprintf(Passwd, "%s", p); iePassword = StringCRC32(tu(p)); Syslog('i', "Password : %s (%ld)", p, iePassword); ieBirthDate = xstrcpy(sel_brace(NULL)); Syslog('i', "Birthdate : %s", MBSE_SS(ieBirthDate)); p = sel_brace(NULL); ieTerminal = strtok(p, ","); ieRows = atoi(strtok(NULL, ",")); ieCols = atoi(strtok(NULL, ",")); ieNulls = atoi(strtok(NULL, ",")); Syslog('i', "Terminal : %s (%d x %d) [%d]", ieTerminal, ieRows, ieCols, ieNulls); p = sel_brace(NULL); Syslog('i', "Protocols : %s", MBSE_SS(p)); for (q = strtok(p, ","); q; q = strtok(NULL, ",")) { if (strcasecmp(q, "DZA") == 0) ieDZA = TRUE; else if (strcasecmp(q, "ZAP") == 0) ieZAP = TRUE; else if (strcasecmp(q, "ZMO") == 0) ieZMO = TRUE; else if (strcasecmp(q, "SLK") == 0) ieSLK = TRUE; else if (strcasecmp(q, "KER") == 0) ieKER = TRUE; else Syslog('+', "Unrecognized IEMSI Protocol \"%s\"", q); } p = sel_brace(NULL); Syslog('i', "Capabilities: %s", MBSE_SS(p)); for (q = strtok(p, ","); q; q = strtok(NULL, ",")) { if (strcasecmp(q, "CHT") == 0) ieCHT = TRUE; else if (strcasecmp(q, "TAB") == 0) ieTAB = TRUE; else if (strcasecmp(q, "MNU") == 0) ieMNU = TRUE; else if (strcasecmp(q, "ASCII8") == 0) ieASCII8 = TRUE; else Syslog('+', "Unrecognized IEMSI Capability \"%s\"", q); } p = sel_brace(NULL); Syslog('i', "Requests : %s", MBSE_SS(p)); for (q = strtok(p, ","); q; q = strtok(NULL, ",")) { if (strcasecmp(q, "NEWS") == 0) ieNEWS = TRUE; else if (strcasecmp(q, "MAIL") == 0) ieMAIL = TRUE; else if (strcasecmp(q, "FILE") == 0) ieFILE = TRUE; else if (strcasecmp(q, "HOT") == 0) ieHOT = TRUE; else if (strcasecmp(q, "CLR") == 0) ieCLR = TRUE; else if (strcasecmp(q, "HUSH") == 0) ieHUSH = TRUE; else if (strcasecmp(q, "MORE") == 0) ieMORE = TRUE; else if (strcasecmp(q, "FSED") == 0) ieFSED = TRUE; else if (strcasecmp(q, "XPRS") == 0) ieXPRS = TRUE; else Syslog('+', "Unrecognized IEMSI Request \"%s\"", q); } ieSoftware = xstrcpy(sel_brace(NULL)); Syslog('i', "Software : %s", MBSE_SS(ieSoftware)); return 0; } char *mkiemsiisi(void); char *mkiemsiisi(void) { char *p, cbuf[16]; time_t tt; p = xstrcpy((char *)"EMSI_ISI0000{MBSE BBS,"); p = xstrcat(p, (char *)VERSION); p = xstrcat(p, (char *)",Linux}{"); p = xstrcat(p, CFG.bbs_name); p = xstrcat(p, (char *)"}{"); p = xstrcat(p, CFG.location); p = xstrcat(p, (char *)"}{"); p = xstrcat(p, CFG.sysop_name); p = xstrcat(p, (char *)"}{"); (void)time(&tt); sprintf(cbuf, "%08lX", mktime(localtime(&tt))); p = xstrcat(p, cbuf); p = xstrcat(p, (char *)"}{"); p = xstrcat(p, CFG.comment); p = xstrcat(p, (char *)"}{0}{}"); sprintf(cbuf, "%04X", (unsigned int)strlen(p+12)); memcpy(p+8, cbuf, 4); Syslog('i', "Prepared \"%s\"", p); return p; } SM_DECL(rxemsi, (char *)"rxemsi") SM_STATES prompt, getpkt, chkpkt, chkici, sendnak, sendisi, human SM_NAMES (char *)"prompt", (char *)"getpkt", (char *)"chkpkt", (char *)"chkici", (char *)"sendnak", (char *)"sendisi", (char *)"human" SM_EDECL int len, iemsi, newpos, tries = 0; char *p, *buf = NULL; unsigned char c = 0; unsigned short lcrc, rcrc; unsigned long llcrc, lrcrc; buf = calloc(2048, sizeof(char)); SM_START(prompt) SM_STATE(prompt) Syslog('I', "SM: prompt"); /* * Issue EMSI_IRQ and overwrite it with the prompt. */ printf("**EMSI_IRQ8E08\r \r"); /* Please enter your First and Last name: */ language(7, 0, 0); fflush(stdout); tries = 0; SM_PROCEED(getpkt); SM_STATE(getpkt) Syslog('I', "SM: getpkt"); fflush(stdin); if ((ttyfd = open("/dev/tty", O_RDWR|O_NONBLOCK)) < 0) { WriteError("$Can't open /dev/tty"); SM_ERROR; } Setraw(); len = 0; iemsi = FALSE; newpos = 0; buf[0] = '\0'; alarm_on(); while(TRUE) { c = Readkey(); Syslog('I', "c=%s len=%d iemsi=%d", printablec(c), len, iemsi); if ((len == 0) && (c == '*')) { iemsi = TRUE; } else { if (((c == 8) || (c == KEY_DEL) || (c == 127)) && (len > 0)) { printf("\b \b"); fflush(stdout); buf[--len] = '\0'; } if (c > 31 && c < 127) { if ((len == 0) && (CFG.iCapUserName)) c = toupper(c); if (c == 32) { newpos = len; newpos++; } if (!iemsi) { if (newpos == len && CFG.iCapUserName) c = toupper(c); else { if (CFG.iCapUserName) c = tolower(c); } printf("%c", c); fflush(stdout); } buf[len] = c; len++; } } if ((c == '\r') || (!iemsi && (len == 35)) || (iemsi && (len == 2047))) { buf[len] = '\0'; break; } } Unsetraw(); close(ttyfd); Syslog('I', "Buf \"%s\"", printable(buf,0)); if (strncasecmp(buf, "EMSI_", 5)) { SM_PROCEED(human); } else { SM_PROCEED(chkpkt); } SM_STATE(chkpkt) Syslog('I', "SM: chkpkt"); if (strncasecmp(buf, "EMSI_ICI", 8) == 0) { SM_PROCEED(chkici) } lcrc = crc16xmodem(buf, 8); sscanf(buf+8, "%04hx", &rcrc); if (lcrc != rcrc) { Syslog('+', "Got IEMSI packet \"%s\" with bad crc: %04x/%04x", printable(buf, 0), lcrc, rcrc); SM_PROCEED(sendnak); } if (strncasecmp(buf, "EMSI_HBT", 8) == 0) { tries = 0; SM_PROCEED(getpkt); } else if (strncasecmp(buf, "EMSI_IIR61E2", 12) == 0) { Syslog('+', "IEMSI Interrupt Request received"); SM_ERROR; } else if (strncasecmp(buf, "EMSI_ACKA490", 12) == 0) { Syslog('+', "Established IEMSI session"); ieLogin = TRUE; /* * Clearup the part of the users screen where some IEMSI * codes may be hanging around */ fflush(stdin); printf("\r \r"); fflush(stdout); SM_SUCCESS; } else if (strncasecmp(buf, "EMSI_NAKEEC3", 12) == 0) { Syslog('+', "IEMSI NAK received"); SM_PROCEED(getpkt); } else { Syslog('I', "rxemsi ignores packet \"%s\"", buf); SM_PROCEED(getpkt); } SM_STATE(chkici) Syslog('I', "SM: chkici"); sscanf(buf+8, "%04x", &len); if (len != (strlen(buf) - 20)) { Syslog('+', "Bad EMSI_ICI length: %d/%d", len, strlen(buf)-20); SM_PROCEED(sendnak); } sscanf(buf+strlen(buf)-8, "%08lx", &lrcrc); *(buf+strlen(buf)-8) = '\0'; llcrc = crc32ccitt(buf, strlen(buf)); if (llcrc != lrcrc) { Syslog('+', "Got EMSI_ICI packet \"%s\" with bad crc: %08x/%08x", printable(buf, 0), llcrc, lrcrc); SM_PROCEED(sendnak); } if (scanemsiici(buf+12) == 0) { SM_PROCEED(sendisi); } else { WriteError("Could not parse EMSI_ICI packet \"%s\"", buf); SM_ERROR; } SM_STATE(sendnak) Syslog('I', "SM: sendnak"); if (++tries > 9) { Syslog('+', "too many tries getting EMSI_ICI"); SM_ERROR; } printf((char *)"**EMSI_IRQ8E08\r"); if (tries > 1) printf((char *)"**EMSI_NAKEEC3\r"); fflush(stdout); SM_PROCEED(getpkt); SM_STATE(sendisi) Syslog('I', "SM: sendisi"); p = mkiemsiisi(); printf("**%s%08lX\r", p, crc32ccitt(p, strlen(p))); fflush(stdout); free(p); SM_PROCEED(getpkt); SM_STATE(human) printf("\n"); fflush(stdout); ieUserName = xstrcpy(buf); Syslog('+', "Human caller (%s)", MBSE_SS(ieUserName)); SM_SUCCESS; SM_END free(buf); SM_RETURN void user() { FILE *pUsrConfig, *pLimits; int i, x, z; int FoundName = FALSE, iFoundLimit = FALSE; register int recno; int lrecno = 0; long l1, l2; unsigned crc = 0; char *token; char temp[PATH_MAX]; char temp1[84]; char sGetName[84]; char *FileName; char *handle; struct passwd *pw; char *sGetPassword; long offset; time_t LastLogin; struct stat st; char UserName[36]; int IsNew = FALSE; recno=0; LoginPrompt = TRUE; /* * If not in unix mode ask for login */ if (!iUnixMode) { strcpy(sGetName, AskLogin()); } else { Syslog('+', "Unixmode login: %s", sUnixName); if ((pw = getpwnam(sUnixName))) strcpy(sGetName, pw->pw_gecos); /* * If there are more fields in the passwd gecos field * then only get the first field. */ if (strchr(sGetName, ',') != NULL) strcpy(sGetName, strtok(sGetName, ",")); if (!(CheckName(sGetName))) { printf("Unknown username: %s\n", sGetName); /* FATAL ERROR: You are not in the BBS users file.*/ printf("%s\n", (char *) Language(389)); /* Please run 'newuser' to create an account */ printf("%s\n", (char *) Language(390)); Syslog('?', "FATAL: Could not find user in BBS users file."); Syslog('?', " and system is using unix accounts\n"); free(Passwd); ExitClient(0); } } if (CFG.iCapUserName || SYSOP) strcpy(sGetName, tlcap(sGetName)); /* * Copy username, split first and lastname. */ strcpy(UserName, tlcap(sGetName)); if ((strchr(sGetName,' ') == NULL && !CFG.iOneName)) { token = strtok(sGetName, " "); strcpy(FirstName, token); token = strtok(NULL, "\0"); i = strlen(token); for(x = 2; x < i; x++) { if(token[x] == ' ') token[x] = '\0'; } strcpy(LastName, token); } else strcpy(FirstName, sGetName); Syslog('+', "%s On-Line at %s", UserName, ttyinfo.comment); if ((strlen(sGetName)) < 2) user(); /* * Check some essential files, create them if they don't exist. */ ChkFiles(); sprintf(temp, "%s/etc/users.data", getenv("MBSE_ROOT")); if ((pUsrConfig = fopen(temp,"r+b")) == NULL) { /* * This should only happen once, when you build the BBS */ WriteError("Can't open users file: %s", temp); printf("Can't open userfile, run \"newuser\" first"); free(Passwd); ExitClient(0); } handle = calloc(40, sizeof(char)); fread(&usrconfighdr, sizeof(usrconfighdr), 1, pUsrConfig); strcpy(temp1, UserName); while (fread(&usrconfig, usrconfighdr.recsize, 1, pUsrConfig) == 1) { strcpy(temp, usrconfig.sUserName); strcpy(handle, usrconfig.sHandle); if ((strcasecmp(temp, temp1) == 0 || strcasecmp(handle, temp1) == 0)) { FoundName = TRUE; break; } else recno++; } free(handle); if (!FoundName) { Syslog('+', "Name not in user file"); Enter(1); /* Scanning User File */ language(LIGHTGRAY, BLACK, 3); Enter(1); usrconfig.GraphMode = FALSE; DisplayFile((char *)"notfound"); Enter(1); /* Name entered: */ language(LIGHTGRAY, BLACK, 5); printf("%s\n\n", UserName); /* Did you spell your name correctly [Y/n] */ language(WHITE, BLACK, 4); fflush(stdout); fflush(stdin); i = toupper(Getone()); if (i == Keystroke(4, 0) || i == '\r') { if (!CFG.elite_mode) { /* * Here we run newuser. */ Syslog('+', "Creating user ..."); recno = newuser(UserName); IsNew = TRUE; } else { if (!DisplayFile((char *)"private")) { /* If FALSE display hard coded message */ Enter(1); /* This is a PRIVATE System, Type "off" to leave */ language(LIGHTRED, BLACK, 6); Enter(2); } Syslog('!', "NewUser tried to login to \"Private System\""); free(Passwd); Quick_Bye(0); } } else { Enter(1); Syslog('+', "User spelt his/her name incorrectly"); user(); } } /* * Setup users favourite language. */ Set_Language(usrconfig.iLanguage); Free_Language(); InitLanguage(); /* * User logged in, tell it to the server. */ UserCity(mypid, usrconfig.sUserName, usrconfig.sLocation); /* * See if this user is the Sysop. */ strcpy(temp, UserName); strcpy(temp1, CFG.sysop_name); if ((strcasecmp(temp1, temp)) == 0) SYSOP = TRUE; /* If login name is sysop, set SYSOP true */ grecno = recno; offset = usrconfighdr.hdrsize + (recno * usrconfighdr.recsize); if (fseek(pUsrConfig, offset, 0) != 0) { printf("Can't move pointer there."); getchar(); free(Passwd); ExitClient(1); } fread(&usrconfig, usrconfighdr.recsize, 1, pUsrConfig); TermInit(usrconfig.GraphMode); sGetPassword = malloc(Max_passlen+1); /* * If UnixMode is False, else let crc = iPassword to bypass the * passwd */ if (!iUnixMode && !IsNew) { /* * Check for a blank or expired password, they do exist * after upgrading from RA 2.xx due to a bug in RA (or feature) */ if (usrconfig.iPassword == 0) { Syslog('!', "User has blank password, asking new"); z = 0; while (TRUE) { Enter(1); /* Your password is expired, enter password: */ language(LIGHTGRAY, BLACK, 435); fflush(stdout); alarm_on(); Getpass(temp); if ((x = strlen(temp)) >= CFG.password_length) { Enter(1); /* Please enter password again: */ language(LIGHTGRAY, BLACK, 40); fflush(stdout); alarm_on(); Getpass(temp1); if ((i = strcmp(temp, temp1)) != 0) { Enter(2); /* Passwords do not match */ language(LIGHTRED, BLACK, 41); Enter(1); } else { memset(&usrconfig.Password, 0, sizeof(usrconfig.Password)); sprintf(usrconfig.Password, "%s", temp); memset(Passwd, 0, 16); sprintf(Passwd, "%s", temp); crc = StringCRC32(tu(temp)); usrconfig.iPassword = crc; break; } } else { z++; if (z == CFG.iCRLoginCount) { Syslog('!', "User did not enter new password"); Enter(1); language(CFG.HiliteF, CFG.HiliteB, 2); Enter(2); free(Passwd); Quick_Bye(0); } Enter(2); /* Your password must contain at least */ language(LIGHTRED, BLACK, 42); printf("%d ", CFG.password_length); /* characters! Try again */ language(LIGHTRED, BLACK, 43); Enter(1); } } } else { if ((ieLogin) && (iePassword == usrconfig.iPassword)) { crc = iePassword; } else { /* Pasword: */ language(LIGHTGRAY, BLACK, 8); fflush(stdout); alarm_on(); Getpass(sGetPassword); /* * Password is CRC32 of uppercase string */ memset(Passwd, 0, 16); sprintf(Passwd, "%s", sGetPassword); memset(&usrconfig.Password, 0, sizeof(usrconfig.Password)); sprintf(usrconfig.Password, "%s", sGetPassword); crc = StringCRC32(tu(sGetPassword)); } } } else { crc = usrconfig.iPassword; sprintf(Passwd, "%s", usrconfig.Password); } IsDoing("Just Logged In"); /* * If password already OK, give pause prompt so the bbs logo * will stay on the users screen. */ if ((iUnixMode) || ((ieLogin) && (iePassword == usrconfig.iPassword))) { alarm_on(); Pause(); } if (usrconfig.Archiver[0] == '\0') { usrconfig.Archiver[0] = 'Z'; usrconfig.Archiver[1] = 'I'; usrconfig.Archiver[2] = 'P'; Syslog('+', "Setup default archiver ZIP"); } if (usrconfig.iPassword == crc) { recno = 0; free(sGetPassword); /* * Check if user has an Unix account, if not create one */ if (usrconfig.Name[0] == '\0') { alarm_on(); sprintf(usrconfig.Name, "%s", (char *)NameCreate(NameGen(UserName), UserName, Passwd)); sprintf(sUnixName, "%s", usrconfig.Name); Pause(); } /* * Check users date format. We do it strict as we * need this to be good for several other purposes. * If it is correct, the users age is set in UserAge */ if (!Test_DOB(usrconfig.sDateOfBirth)) { Syslog('!', "Error in Date of Birth"); Chg_DOB(); strcpy(usrconfig.sDateOfBirth, exitinfo.sDateOfBirth); } /* * Check to see if user must expire */ sprintf(temp,"%s", (char *) GetDateDMY()); SwapDate(temp, usrconfig.sExpiryDate); /* Convert Date1 & Date2 to longs for compare */ l1 = atol(Date1); l2 = atol(Date2); if(l1 >= l2 && l2 != 0) { /* * If Expiry Date is the same as today expire to * Expire Sec level */ usrconfig.Security = usrconfig.ExpirySec; Syslog('!', "User is expired, resetting level"); /* * Show texfile to user telling him about this. */ DisplayFile((char *)"expired"); } free(Date1); free(Date2); /* * Copy limits.data into memory */ FileName = calloc(84, sizeof(char)); sprintf(FileName, "%s/etc/limits.data", getenv("MBSE_ROOT")); if(( pLimits = fopen(FileName,"rb")) == NULL) { perror(""); WriteError("Can't open file: %s", FileName); } else { fread(&LIMIThdr, sizeof(LIMIThdr), 1, pLimits); while (fread(&LIMIT, sizeof(LIMIT), 1, pLimits) == 1) { if (LIMIT.Security == usrconfig.Security.level) { iFoundLimit = TRUE; break; } else lrecno++; } fclose(pLimits); } free(FileName); if(!iFoundLimit) { Syslog('?', "Unknown Security Level in limits.data"); usrconfig.iTimeLeft = 0; /* Could not find limit, so set to Zero */ usrconfig.iTimeUsed = 0; /* Set to Zero as well */ } else { /* * Give user new time limit everyday */ sprintf(temp,"%s", (char *) GetDateDMY()); if((strcmp(StrDateDMY(usrconfig.tLastLoginDate), temp)) != 0) { /* * If no timelimit set give user 24 hours. */ if (LIMIT.Time) usrconfig.iTimeLeft = LIMIT.Time; else usrconfig.iTimeLeft = 86400; usrconfig.iTimeUsed = 0; /* Set time used today to Zero */ usrconfig.iConnectTime = 0; /* Set connect time to Zero */ /* * Give user new bytes and files every day if needed. */ if (LIMIT.DownK && LIMIT.DownF) { usrconfig.DownloadKToday = LIMIT.DownK; usrconfig.DownloadsToday = LIMIT.DownF; } } } /* End of else */ usrconfig.iConnectTime = 0; /* Copy Users Protocol into Memory */ Set_Protocol(usrconfig.sProtocol); tlf(usrconfig.sProtocol); /* * Set last login Date and Time, copy previous session * values in memory. */ sprintf(LastLoginDate, "%s", StrDateDMY(usrconfig.tLastLoginDate)); sprintf(LastLoginTime, "%s", StrTimeHMS(usrconfig.tLastLoginDate)); LastLogin = usrconfig.tLastLoginDate; usrconfig.tLastLoginDate = ltime; /* Set current login to current date */ usrconfig.iTotalCalls = ++usrconfig.iTotalCalls; memset(&usrconfig.Password, 0, sizeof(usrconfig.Password)); sprintf(usrconfig.Password, "%s", Passwd); /* * If IEMSI login, update some settings */ if (ieLogin) { usrconfig.Cls = ieCLR; usrconfig.HotKeys = ieHOT; usrconfig.ieNEWS = ieNEWS; usrconfig.MailScan = ieMAIL; usrconfig.ieFILE = ieFILE; usrconfig.Chat = ieCHT; usrconfig.ieASCII8 = ieASCII8; usrconfig.DoNotDisturb = ieHUSH; usrconfig.FsMsged = ieFSED; } /* * Update user record. */ if(fseek(pUsrConfig, offset, 0) != 0) WriteError("Can't move pointer in file: %s", temp); else { fwrite(&usrconfig, sizeof(usrconfig), 1, pUsrConfig); fclose(pUsrConfig); } /* * Write users structure to tmp file in ~/tmp */ InitExitinfo(); GetLastUser(); StartTime = xstrcpy(GetLocalHM()); ChangeHomeDir(exitinfo.Name, exitinfo.Email); Syslog('+', "User successfully logged into BBS"); Syslog('+', "Level %d (%s), %d mins. left, port %s", usrconfig.Security.level, LIMIT.Description, usrconfig.iTimeLeft, pTTY); time(&Time2Go); Time2Go += usrconfig.iTimeLeft * 60; iUserTimeLeft = usrconfig.iTimeLeft; DisplayFile((char *)"welcome"); /* * The following files are only displayed if the user has * turned the Bulletins on. */ if (exitinfo.ieNEWS) { DisplayFile((char *)"welcome1"); sprintf(temp, "%s", (char *) GetDateDMY() ); if ((strcmp(usrconfig.sDateOfBirth, temp)) == 0) DisplayFile((char *)"birthday"); /* * Displays file if it exists DD-MM.A?? */ sprintf(temp, "%s", (char *) GetDateDMY()); strcpy(temp1, ""); strncat(temp1, temp, 5); sprintf(temp, "%s", temp1); DisplayFile(temp); /* * Displays users security file if it exists */ sprintf(temp, "sec%d", usrconfig.Security.level); DisplayFile(temp); /* * Display News file */ DisplayFile((char *)"news"); } /* * Display Onceonly file, first get the date of that * file, search order is the same as in DisplayFile() */ st.st_mtime = 0; if (usrconfig.GraphMode) { sprintf(temp, "%s/onceonly.ans", lang.TextPath); stat(temp, &st); if (st.st_mtime == 0) { sprintf(temp, "%s/onceonly.ans", CFG.bbs_txtfiles); stat(temp, &st); } } if (st.st_mtime == 0) { sprintf(temp, "%s/onceonly.asc", lang.TextPath); stat(temp, &st); if (st.st_mtime == 0) { sprintf(temp, "%s/onceonly.asc", CFG.bbs_txtfiles); stat(temp, &st); } } if ((st.st_mtime != 0) && (LastLogin < st.st_mtime)) DisplayFile((char *)"onceonly"); LoginPrompt = FALSE; OLR_SyncTags(); if (usrconfig.MailScan) CheckMail(); /* * We don't show new files to new users, their lastlogin * date is not yet set so they would see all the files * which can be boring... */ if (usrconfig.ieFILE && (!IsNew)) NewfileScan(FALSE); /* * Copy last file Area in to current Area */ SetFileArea(usrconfig.iLastFileArea); /* * Copy Last Message Area in to Current Msg Area */ SetMsgArea(usrconfig.iLastMsgArea); SetEmailArea((char *)"mailbox"); /* * Set or Reset the DoNotDisturb flag, now is the time * we may be interrupted. */ UserSilent(usrconfig.DoNotDisturb); /* * Start the menu, but first, wipe the password. */ memset(Passwd, 0, sizeof(Passwd)); free(Passwd); menu(); } else { Syslog('+',"Login attempt: %d, password: %s", iMaxLogin, sGetPassword); free(sGetPassword); iMaxLogin++; if(iMaxLogin == CFG.max_login + 1) { Enter(2); language(LIGHTGRAY, BLACK, 9); Enter(1); Syslog('!', "Exceeded maximum login attempts, user disconnected"); ExitClient(1); } Enter(2); language(LIGHTGRAY, BLACK, 10); Enter(2); alarm_on(); Pause(); printf("\n"); user(); } }