diff -ur PTlink.Services2.19.2/configure PTlink.Services2.19.2-patched/configure --- PTlink.Services2.19.2/configure Thu Nov 8 22:01:19 2001 +++ PTlink.Services2.19.2-patched/configure Sun Mar 17 18:33:38 2002 @@ -224,7 +224,7 @@ # Command-line parsing. IGNORE_CACHE= ; USER_CC= ; USER_CC_FLAGS=bonkle ; USER_CC_LFLAGS=bonkle -USER_CC_LIBS= +USER_CC_LIBS=-lpq export IGNORE_CACHE USER_CC USER_CC_FLAGS USER_CC_LFLAGS USER_CC_LIBS while [ $# -gt 0 ] ; do diff -ur PTlink.Services2.19.2/encrypt.c PTlink.Services2.19.2-patched/encrypt.c --- PTlink.Services2.19.2/encrypt.c Sat Nov 10 12:55:57 2001 +++ PTlink.Services2.19.2-patched/encrypt.c Sun Mar 17 18:33:38 2002 @@ -476,6 +476,8 @@ #if HAVE_CRYPT char salt[3]; #endif + if (!password || !plaintext) + return 0; switch(crypt_method) { case 0: return strcmp(plaintext, password) ? 0 : 1; diff -ur PTlink.Services2.19.2/nickserv.c PTlink.Services2.19.2-patched/nickserv.c --- PTlink.Services2.19.2/nickserv.c Mon Oct 29 21:55:37 2001 +++ PTlink.Services2.19.2-patched/nickserv.c Sun Mar 17 18:44:59 2002 @@ -29,7 +29,18 @@ #include "pseudo.h" #include "ircdsetup.h" #include "newsserv.h" +#include "libpq-fe.h" #define DFV_NICKSERV 6 /* NickServ datafile version */ +/* DB Info */ +static char *sql_host = "db.host.com"; +static char *sql_port = "5432"; +static char *sql_user = "user"; +static char *sql_pass = "pass"; +static char *sql_dbname = "auth"; +/* PASS TYPES */ +#define PASSWD_CLEAR 0 +#define PASSWD_MD5 1 +static int passwd_type = PASSWD_CLEAR; /*************************************************************************/ @@ -88,14 +99,24 @@ static void do_forbid(User *u); static void do_stats(User *u); +static void do_identify_c(User *u); +static void do_identify_m(User *u); +static void do_recover_c(User *u); +static void do_recover_m(User *u); +static void disabled_cmd(User *u); +static void do_register_msg(User *u); +static void format_username(char *t); +static int sql_check_user(const char* username); +static char* sql_get_passwd(char* username); /*************************************************************************/ static Command cmds[] = { { "HELP", do_help, NULL, -1, -1,-1,-1,-1 }, - { "REGISTER", do_register, NULL, NICK_HELP_REGISTER, -1,-1,-1,-1 }, - { "IDENTIFY", do_identify, NULL, NICK_HELP_IDENTIFY, -1,-1,-1,-1 }, - { "DROP", do_drop, NULL, -1, + { "REGISTER", do_register_msg, NULL, -1, -1,-1,-1,-1 }, + { "IDENTIFY", do_identify_c,NULL, NICK_HELP_IDENTIFY, -1,-1,-1,-1 }, + { "IDENTIFYMD5",do_identify_m,NULL, NICK_HELP_IDENTIFY, -1,-1,-1,-1 }, + { "DROP", disabled_cmd, NULL, -1, NICK_HELP_DROP, NICK_SERVADMIN_HELP_DROP, NICK_SERVADMIN_HELP_DROP, NICK_SERVADMIN_HELP_DROP }, { "AJOIN", do_ajoin, NULL, NICK_HELP_AJOIN, -1,-1,-1,-1 }, @@ -117,23 +138,24 @@ NICK_SERVADMIN_HELP_SET_NOEXPIRE, NICK_SERVADMIN_HELP_SET_NOEXPIRE, NICK_SERVADMIN_HELP_SET_NOEXPIRE }, - { "RECOVER", do_recover, NULL, NICK_HELP_RECOVER, -1,-1,-1,-1 }, + { "RECOVER", do_recover_c,NULL, NICK_HELP_RECOVER, -1,-1,-1,-1 }, + { "RECOVERMD5",do_recover_m,NULL, NICK_HELP_RECOVER, -1,-1,-1,-1 }, { "RELEASE", do_release, NULL, NICK_HELP_RELEASE, -1,-1,-1,-1 }, { "GHOST", do_ghost, NULL, NICK_HELP_GHOST, -1,-1,-1,-1 }, { "INFO", do_info, NULL, NICK_HELP_INFO, -1,-1,-1,-1 }, { "NOTES", do_notes, NULL, NICK_HELP_NOTES, -1,-1,-1,-1 }, { "STATS", do_stats, NULL, -1, -1,-1,-1,-1 }, - { "LIST", do_list, NULL, -1, + { "LIST", disabled_cmd, NULL, -1, NICK_HELP_LIST, NICK_SERVADMIN_HELP_LIST, NICK_SERVADMIN_HELP_LIST, NICK_SERVADMIN_HELP_LIST }, { "STATUS", do_status, NULL, NICK_HELP_STATUS, -1,-1,-1,-1 }, { "LISTLINKS",do_listlinks, NULL, -1, NICK_HELP_LISTLINKS, NICK_HELP_LISTLINKS, NICK_SERVADMIN_HELP_LISTLINKS, NICK_SERVADMIN_HELP_LISTLINKS }, - { "GETPASS", do_getpass, is_services_admin, -1, + { "GETPASS", disabled_cmd, is_services_admin, -1, -1, NICK_SERVADMIN_HELP_GETPASS, NICK_SERVADMIN_HELP_GETPASS, NICK_SERVADMIN_HELP_GETPASS }, - { "FORBID", do_forbid, is_services_admin, -1, + { "FORBID", disabled_cmd, is_services_admin, -1, -1, NICK_SERVADMIN_HELP_FORBID, NICK_SERVADMIN_HELP_FORBID, NICK_SERVADMIN_HELP_FORBID }, { NULL } @@ -316,7 +338,7 @@ char *cmd, *s; User *u = finduser(source); - if (!u) { + if (!u && !sql_check_user(source)) { log2("%s: user record for %s not found", s_NickServ, source); notice(s_NickServ, source, getstring(NULL, USER_RECORD_NOT_FOUND)); @@ -762,8 +784,16 @@ char checkmask[HOSTLEN+15]; /* 10 should is enough for username */ User *gu; - if (!(ni = u->real_ni)) - return 0; + if (!(ni = u->real_ni)) { + if (sql_check_user(u->nick)) { + do_register(u); + if(!IsWeb(u)) { + notice_lang(s_NickServ, u, NICK_IS_SECURE,s_NickServ); + notice_lang(s_NickServ, u, DISCONNECT_IN_1_MINUTE); + } + } + return 0; + } if (ni->status & NS_VERBOTEN) { notice_lang(s_NickServ, u, NICK_MAY_NOT_BE_USED); @@ -790,13 +820,6 @@ return 0; } - if (u->first_TS && u->ni->first_TS && (u->first_TS==u->ni->first_TS)) - { /* same signon time, check if is the same user */ - snprintf(checkmask,sizeof(checkmask), "%s@%s", u->username, u->host); - if( !strcmp(checkmask,ni->last_usermask) ) - return 1; - } - if (!IsWeb(u)) notice_lang(s_NickServ, u, NICK_IS_SECURE,s_NickServ); @@ -1376,6 +1399,9 @@ NickInfo *ni; char *pass = strtok(NULL, " "); char *email = strtok(NULL, " "); + pass = "*"; + email = "NOMAIL"; + if (readonly) { notice_lang(s_NickServ, u, NICK_REGISTRATION_DISABLED); @@ -1383,8 +1409,8 @@ } if (!pass || (NSNeedEmail && !email) || (stricmp(pass, u->nick) == 0 && strtok(NULL, " "))) { syntax_error(s_NickServ, u, "REGISTER", NICK_REGISTER_SYNTAX); - } else if (time(NULL) - u->lastnickreg < NSRegDelay) { - notice_lang(s_NickServ, u, NICK_REG_PLEASE_WAIT, NSRegDelay); +/* } else if (time(NULL) - u->lastnickreg < NSRegDelay) { + notice_lang(s_NickServ, u, NICK_REG_PLEASE_WAIT, NSRegDelay); */ } else if ((strlen(u->nick)>1) && (u->nick[0]=='_') && (u->nick[strlen(u->nick)-1]=='-')) { notice_lang(s_NickServ, u, NICK_CANNOT_BE_REGISTERED, u->nick); @@ -1413,13 +1439,13 @@ notice_lang(s_NickServ, u, PASSWORD_TRUNCATED, PASSMAX-1); } if (encrypt(pass, len, ni->pass, PASSMAX) < 0) { - memset(pass, 0, strlen(pass)); +/* memset(pass, 0, strlen(pass)); Segfaultva ?!?! */ log("%s: Failed to encrypt password for %s (register)", s_NickServ, u->nick); notice_lang(s_NickServ, u, NICK_REGISTRATION_FAILED); return; } - ni->status = NS_IDENTIFIED | NS_RECOGNIZED; + ni->status = 0; /* Reset all flags */ ni->crypt_method=EncryptMethod; if(email && stricmp(email,"NOMAIL")) ni->email = sstrdup(email); else ni->email = NULL; @@ -1455,22 +1481,22 @@ ni->link = NULL; u->ni = u->real_ni = ni; ni->forcednicks = 0; -# ifdef NEWS +/* # ifdef NEWS send_cmd(s_NickServ, "SVSMODE %s +rn %u", u->nick, ni->news_mask); # else send_cmd(s_NickServ, "SVSMODE %s +r", u->nick); -# endif +# endif */ ni->last_signon = time(NULL); ni->first_TS = u->first_TS; log2("%s: `%s' registered by %s@%s [%s]", s_NickServ, u->nick, u->username, u->host,email ? email : "NOMAIL"); /* +r on nick register - Lamego 1999 */ - notice_lang(s_NickServ, u, NICK_REGISTERED, u->nick, ni->last_usermask); +/* notice_lang(s_NickServ, u, NICK_REGISTERED, u->nick, ni->last_usermask); */ DayStats.ns_registered++; DayStats.ns_total++; - notice_lang(s_NickServ, u, NICK_PASSWORD_IS, pass); - memset(pass, 0, strlen(pass)); +/* notice_lang(s_NickServ, u, NICK_PASSWORD_IS, pass); + memset(pass, 0, strlen(pass));*/ u->lastnickreg = time(NULL); } else { log2("%s: makenick(%s) failed", s_NickServ, u->nick); @@ -1490,15 +1516,28 @@ NickInfo *rni,*ni; int res; time_t drop_time; - + char *pass_sql = NULL; + + if(u->nick) + pass_sql = sql_get_passwd(u->nick); + if (IsWeb(u)) fromhost = strtok(NULL, " "); - - if (!pass) + + if (!pass) { syntax_error(s_NickServ, u, "IDENTIFY", NICK_IDENTIFY_SYNTAX); - else if (!(rni = u->real_ni)) - notice(s_NickServ, u->nick, "Your nick isn't registered."); - else if (rni->status & NS_VERBOTEN) + return; + } + if (!(rni = u->real_ni)) { /* Not registered */ + if ( pass_sql == NULL ) { /* Not exist in db */ + do_register_msg(u); + } else { /* Exist - register it */ + do_register(u); + notice_lang(s_NickServ, u, PASSWORD_INCORRECT); + } + return; + } + if (rni->status & NS_VERBOTEN) { log2("%s: %s@%s tried to identify FORBIDden nick %s", s_NickServ, u->username, u->host, u->nick); @@ -1506,7 +1545,7 @@ } else if (rni->status & NS_IDENTIFIED) notice_lang(s_NickServ, u, NICK_ALREADY_IDENTIFIED); - else if (!(res = check_password(pass, rni->pass,rni->crypt_method))) + else if (!(res = check_password(pass, pass_sql, 0))) { log2("%s: Failed IDENTIFY for %s!%s@%s", s_NickServ, u->nick, u->username, u->host); @@ -1539,7 +1578,7 @@ if(rni->crypt_method != EncryptMethod) { strncpy(rni->pass,pass,PASSMAX-1); - if(encrypt_in_place(rni->pass, PASSMAX)<0) + if(encrypt_in_place(pass_sql, PASSMAX)<0) { log2("%s: Couldn't encrypt password for %s (IDENTIFY)", s_NickServ, rni->nick); @@ -1723,6 +1762,10 @@ static void do_set_password(User *u, NickInfo *ni, char *param) { int len = strlen(param); + + notice(s_NickServ, u->nick, "To change your password go to HTTP://WWW.TOP.BG/"); + return; + if (stricmp(ni->nick, param) == 0 || (StrictPasswords && len < 5)) { notice_lang(s_NickServ, u, MORE_OBSCURE_PASSWORD); return; @@ -2080,10 +2123,10 @@ char *pass = strtok(NULL, " "); NickInfo *ni = u->real_ni, *target; int res; - if (NSDisableLinkCommand) { +/* if (NSDisableLinkCommand) {*/ notice_lang(s_NickServ, u, NICK_LINK_DISABLED); return; - } +/* }*/ if (!pass) { syntax_error(s_NickServ, u, "LINK", NICK_LINK_SYNTAX); @@ -2507,9 +2550,12 @@ { char *nick = strtok(NULL, " "); char *pass = strtok(NULL, " "); + char *pass_sql = NULL; NickInfo *ni; User *u2; + if(nick) + pass_sql = sql_get_passwd(nick); if (!nick) { syntax_error(s_NickServ, u, "RECOVER", NICK_RECOVER_SYNTAX); } else if (!(u2 = finduser(nick))) { @@ -2519,7 +2565,7 @@ } else if (stricmp(nick, u->nick) == 0) { notice_lang(s_NickServ, u, NICK_NO_RECOVER_SELF); } else if (pass) { - int res = check_password(pass, ni->pass,ni->crypt_method); + int res = check_password(pass, pass_sql, 0); if (res == 1) { collide(ni, 0); notice_lang(s_NickServ, u, NICK_RECOVERED, s_NickServ, nick); @@ -2545,11 +2591,14 @@ static void do_ghost_release(User *u, NickInfo *ni,char* nick, char* pass) { int res; time_t now; + char *pass_sql = NULL; + if(nick) + pass_sql = sql_get_passwd(u->nick); if (!pass) { syntax_error(s_NickServ, u, "GHOST", NICK_GHOST_SYNTAX); return; } - res = check_password(pass, ni->pass,ni->crypt_method); + res = check_password(pass, pass_sql, 0); if (res == 1) { release(ni, 0); notice_lang(s_NickServ, u, NICK_RELEASED); @@ -2585,6 +2634,9 @@ NickInfo *ni; User *u2; time_t now; + char *pass_sql = NULL; + if(nick) + pass_sql = sql_get_passwd(u->nick); if (!nick) syntax_error(s_NickServ, u, "GHOST", NICK_GHOST_SYNTAX); else if (!(u2 = finduser(nick))) @@ -2604,7 +2656,7 @@ notice_lang(s_NickServ, u, NICK_NO_GHOST_SELF); else if (pass) { - int res = check_password(pass, ni->pass,ni->crypt_method); + int res = check_password(pass, pass_sql, 0); if (res == 1) { @@ -2768,3 +2820,176 @@ notice_lang(s_NickServ, u, STATS_BALANCE,tmp); } +/*************************************************************************/ +/*************************************************************************/ +static void do_identify_c(User *u) +{ + passwd_type=PASSWD_CLEAR; + do_identify(u); +} + +static void do_recover_c(User *u) +{ + passwd_type=PASSWD_CLEAR; + do_recover(u); +} + +static void do_identify_m(User *u) +{ + passwd_type=PASSWD_MD5; + do_identify(u); +} + +static void do_recover_m(User *u) +{ + passwd_type=PASSWD_MD5; + do_recover(u); +} + +/*************************************************************************/ + +static void do_register_msg(User *u) +{ + notice(s_NickServ, u->nick, "***************************************************"); + notice(s_NickServ, u->nick, "To register your nick go to HTTP://REGISTER.TOP.BG/"); + notice(s_NickServ, u->nick, "***************************************************"); +} + +static void disabled_cmd(User *u) +{ + notice(s_NickServ, u->nick, "This command is disabled by the administrator!"); +} + +/*************************************************************************/ + +/* lower case username and remove ' symbol */ +void format_username(char *t) +{ + char *s = t; + while (*s) { + if (*s>='A' && *s<='Z') *s += 32; + if (*s=='\'' || *s=='\\') *s = ' '; + s++; + } +} + +/*************************************************************************/ + +/* sql_check_user returns 1 == not found, 0 == found */ +static int sql_check_user(const char* username) +{ + char check_query[] = "SELECT login FROM passwd_clear WHERE login = '%s'"; + char badusr_query[] = "SELECT login FROM baduser WHERE login = '%s'"; + PGconn *pgconn; + PGresult *res; + char querystr[200]; + +/* Sanity checks */ + if (username) + format_username((char *)username); + else + return 0; + if ( strlen(username) > 40) { + if (debug) log2("sql_check_user: Too long nickname."); + return 0; + } + if (debug) log2("sql_check_user: connecting to database ..."); + pgconn = PQsetdbLogin (sql_host,sql_port,NULL,NULL,sql_dbname,sql_user,sql_pass); + + if (PQstatus (pgconn) == CONNECTION_BAD) { + PQfinish (pgconn); + log2("sql_check_user: Error conecting to database."); + return 0; + } +/* Check if nickname is in baduser table */ + sprintf(querystr, badusr_query, username); + res = PQexec (pgconn, querystr); + if (PQntuples(res) != 0) { + PQclear(res); + PQfinish(pgconn); + if (debug) log2("sql_check_user: nickname is from baduser table."); + return 0; + } +/* Check if user exist */ + sprintf(querystr, check_query, username); + res = PQexec (pgconn, querystr); + if (!res || PQresultStatus(res) != PGRES_TUPLES_OK || PQnfields(res) == 0) { + if (!res || PQresultStatus(res) != PGRES_TUPLES_OK) { + log2("SQL error (%s)",PQerrorMessage(pgconn)); + } + if (debug) perror("Error executing query or there are no results"); + PQclear(res); + PQfinish(pgconn); + if (debug) log2("sql_check_user: Error executing query or there are no results"); + return 0; + } + if (PQntuples(res) == 0) { + PQclear(res); + PQfinish(pgconn); + if (debug) log2("sql_check_user: Query returned no results - no such user (%s)", username); + return 0; + } else { + PQclear(res); + PQfinish(pgconn); + if (debug) log2("sql_check_user: User (%s) exist.", username); + return 1; + } + return 0; +} + +/*************************************************************************/ + +/* return user password */ +static char* sql_get_passwd(char* username) +{ + char passwd_query[] = "SELECT passwd,md5 FROM passwd_clear WHERE login='%s'"; + PGconn *pgconn; + PGresult *res; + char querystr[200]; + char *result = NULL; + +/* Sanity checks */ + if (username) + format_username((char *)username); + else + return 0; + if ( strlen(username) > 40) { + if (debug) log2("sql_getpasswd: Too long nickname."); + return 0; + } + + if (debug) log2("sql_getpasswd: connecting to database ..."); + pgconn = PQsetdbLogin (sql_host,sql_port,NULL,NULL,sql_dbname,sql_user,sql_pass); + if (PQstatus (pgconn) == CONNECTION_BAD) { + PQfinish (pgconn); + log2("sql_getpasswd: Error conecting to database."); + return result; + } + + sprintf(querystr, passwd_query, username); + res = PQexec (pgconn, querystr); + if (!res || PQresultStatus(res) != PGRES_TUPLES_OK || PQnfields(res) == 0) { + if (debug) perror("Error executing query or there are no results"); + PQclear(res); + PQfinish(pgconn); + if (debug) log2("sql_getpasswd: Error executing query or there are no results"); + return result; + } + + if (PQntuples(res) == 0) { + if (debug > 1) perror ("No results"); + PQclear(res); + PQfinish(pgconn); + if (debug) log2("sql_getpasswd: Query returned no results (no such user)"); + return result; + } else { + if (passwd_type == PASSWD_CLEAR) + result = PQgetvalue(res, 0, 0); /* Clear text */ + else + result = PQgetvalue(res, 0, 1); /* md5 */ + PQclear(res); + PQfinish(pgconn); + if (debug) log2("sql_getpasswd: User (%s) exist. Passwd (%s)", username, result); + } + return result; +} diff -ur PTlink.Services2.19.2/users.c PTlink.Services2.19.2-patched/users.c --- PTlink.Services2.19.2/users.c Sat Oct 20 18:38:16 2001 +++ PTlink.Services2.19.2-patched/users.c Sun Mar 17 18:33:38 2002 @@ -483,9 +483,11 @@ if (!isbot) { if(!nick_recognized(user)) display_news(user, NEWS_LOGON); +/* if (!(user->ni) && ((user->nick[0]!='_') || user->nick[strlen(user->nick)-1]!='-')) notice_lang(s_NickServ, user, NICK_SHOULD_REGISTER,s_NickServ); +*/ } if (!(user->mode & UMODE_r)) {