00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00042 #include <stdio.h>
00043 #include <stdlib.h>
00044 #include <string.h>
00045 #include <stddef.h>
00046 #include <sys/types.h>
00047 #include <sys/socket.h>
00048
00049 #include "services.h"
00050 #include "options.h"
00051 #include "sipc.h"
00052 #include "nickserv.h"
00053 #include "chanserv.h"
00054 #include "hash/md5.h"
00055 #include "hash/md5pw.h"
00056 #include "log.h"
00057 extern FILE *corelog;
00058
00059 int ipcPort = 0;
00060
00061 int NickGetEnc(RegNickList *);
00062 int ChanGetEnc(RegChanList *);
00063 const char *GetAuthChKey(const char*, const char*, time_t, u_int32_t);
00064 const char *PrintPass(u_char pI[], char enc);
00065 extern RegId top_regnick_idnum;
00066
00067
00068
00070 struct ssUInfo{
00071 char *userName;
00072 char *password;
00073 flag_t priv;
00074 };
00075
00076 const ssUInfo *getServicesSysUser(const char *username)
00077 {
00078 static ssUInfo users[] = {
00079 {"WWW/ahurt", "test", PRIV_QUERY_NICK_ISREG | PRIV_LOGW},
00080 {"WWW/setpass", "test", PRIV_ALTER_RNICK_GEN | PRIV_RCHAN_LOGIN | PRIV_RNICK_LOGIN },
00081 {"mysid/test", "test", PRIV_QUERY_NICK_ISREG | PRIV_QUERY_NICK_PUBLIC | PRIV_QUERY_AKILL_LIST | PRIV_QUERY_NICK_PRIVATE | PRIV_LOGW},
00082 {NULL}
00083 };
00084 int i = 0;
00085
00086 for(i = 0; users[i].userName; i++) {
00087 if (strcmp(users[i].userName, username) == 0)
00088 return &users[i];
00089 }
00090 return NULL;
00091 }
00092
00093
00094
00095
00096 int queryRnickString(RegNickList *rnl, IpcConnectType *p, parse_t *pb, int x);
00097 int queryRnickStringFixed(RegNickList *rnl, IpcConnectType *p, parse_t *pb, int x);
00098 int queryRnickFlag(RegNickList *rnl, IpcConnectType *p, parse_t *pb, int x);
00099 int queryRnickLong(RegNickList *rnl, IpcConnectType *p, parse_t *pb, int x);
00100 int queryRnickUint(RegNickList *rnl, IpcConnectType *p, parse_t *pb, int x);
00101 int queryRnickUchar(RegNickList *rnl, IpcConnectType *p, parse_t *pb, int x);
00102 int queryRnickTime(RegNickList *rnl, IpcConnectType *p, parse_t *pb, int x);
00103
00104 int alterRnickStringD(RegNickList *rnl, IpcConnectType *p, parse_t *pb, int x);
00105 int alterRnickStringFixed(RegNickList *rnl, IpcConnectType *p, parse_t *pb, int x);
00106 int alterRnickEmail(RegNickList *rnl, IpcConnectType *p, parse_t *pb, int x);
00107 int alterRnickFlag(RegNickList *rnl, IpcConnectType *p, parse_t *pb, int x);
00108 int alterRnickLong(RegNickList *rnl, IpcConnectType *p, parse_t *pb, int x);
00109 int alterRnickUint(RegNickList *rnl, IpcConnectType *p, parse_t *pb, int x);
00110 int alterRnickUchar(RegNickList *rnl, IpcConnectType *p, parse_t *pb, int x);
00111 int alterRnickTime(RegNickList *rnl, IpcConnectType *p, parse_t *pb, int x);
00112
00113
00114 #define ORNL(q) (((size_t) &((RegNickList *)0)->q))
00115
00116 struct
00117 {
00118 const char *field;
00119 int (* func)(RegNickList *, IpcConnectType *p, parse_t *pb, int x);
00120 size_t off;
00121 flag_t priv, a_priv;
00122 int (* a_func)(RegNickList *, IpcConnectType *p, parse_t *pb, int x);
00123 }
00124 rnickQueryTable[] =
00125 {
00126 { "URL", queryRnickString, ORNL(url),
00127 0, 0, alterRnickStringD },
00128
00129 { "EMAIL", queryRnickStringFixed, ORNL(email),
00130 PRIV_QUERY_NICK_PRIVATE, PRIV_ALTER_RNICK_2, alterRnickEmail },
00131
00132 { "LAST-HOST-UNMASK", queryRnickString, ORNL(host),
00133 PRIV_QUERY_NICK_UNMASK, PRIV_UNDEF, queryRnickString },
00134
00135 { "FLAGS", queryRnickFlag, ORNL(flags),
00136 PRIV_QUERY_NICK_PUBLIC, PRIV_ALTER_RNICK_3, alterRnickFlag },
00137
00138 { "OPFLAGS", queryRnickFlag, ORNL(opflags),
00139 PRIV_QUERY_NICK_PRIVATE, PRIV_UNDEF, alterRnickFlag },
00140
00141 { "BADPWS", queryRnickUchar, ORNL(badpws),
00142 PRIV_QUERY_NICK_PUBLIC, PRIV_ALTER_RNICK_GEN, alterRnickUchar },
00143
00144 { "TIMEREG", queryRnickTime, ORNL(timereg),
00145 PRIV_QUERY_NICK_PUBLIC, PRIV_ALTER_RNICK_3, alterRnickTime },
00146
00147 { "NUM-MASKS", queryRnickUint, ORNL(amasks),
00148 PRIV_QUERY_NICK_PRIVATE, PRIV_UNDEF, alterRnickTime },
00149
00150 { "IS-READTIME", queryRnickTime, ORNL(is_readtime),
00151 PRIV_QUERY_NICK_PRIVATE, PRIV_ALTER_RNICK_GEN, alterRnickTime },
00152
00153 { NULL }
00154 };
00155
00156
00157
00158 int IpcConnectType::CheckPriv(flag_t pSys, flag_t pObj)
00159 {
00160 if ((pSys & PRIV_UNDEF) || (pObj & PRIV_UNDEF))
00161 return 1;
00162 if ((gpriv & pSys) != pSys)
00163 return 1;
00164
00165 if ((opriv & pObj) != pObj)
00166 return 1;
00167 return 0;
00168 }
00169
00170 int IpcConnectType::CheckOrPriv(flag_t pSys, flag_t pObj)
00171 {
00172 if (!(pSys & PRIV_UNDEF) && (gpriv & pSys) == pSys)
00173 return 0;
00174 if (!(pObj & PRIV_UNDEF) && (opriv & pObj) == pSys)
00175 return 0;
00176 return 1;
00177 }
00178
00179 int queryRnickString(RegNickList *rnl, IpcConnectType *p, parse_t *pb, int x)
00180 {
00181 char *c;
00182 if (!rnl || !rnl->nick) return 0;
00183
00184 c = *(char **)((size_t)rnl + rnickQueryTable[x].off);
00185
00186 if (c != NULL)
00187 p->fWriteLn("OK QUERY OBJECT RNICK=%s %sx %s", rnl->nick,
00188 rnickQueryTable[x].field, c);
00189 else
00190 p->fWriteLn("OK QUERY OBJECT RNICK=%s %sx %s", rnl->nick,
00191 rnickQueryTable[x].field, "");
00192 return 1;
00193 }
00194
00195 int queryRnickStringFixed(RegNickList *rnl, IpcConnectType *p, parse_t *pb, int x)
00196 {
00197 char *c;
00198 if (!rnl || !rnl->nick) return 0;
00199
00200 c = (char *)((size_t)rnl + rnickQueryTable[x].off);
00201
00202 if (c != NULL)
00203 p->fWriteLn("OK QUERY OBJECT RNICK=%s %sx %s", rnl->nick,
00204 rnickQueryTable[x].field, c);
00205 else
00206 p->fWriteLn("OK QUERY OBJECT RNICK=%s %sx %s", rnl->nick,
00207 rnickQueryTable[x].field, "");
00208 return 1;
00209 }
00210
00211 int queryRnickFlag(RegNickList *rnl, IpcConnectType *p, parse_t *pb, int x)
00212 {
00213 flag_t *c = (flag_t *)((size_t)rnl + rnickQueryTable[x].off);
00214
00215 p->fWriteLn("OK QUERY OBJECT RNICK=%s %sx %ld", rnl->nick,
00216 rnickQueryTable[x].field, *c);
00217 return 1;
00218 }
00219
00220 int queryRnickLong(RegNickList *rnl, IpcConnectType *p, parse_t *pb, int x)
00221 {
00222 long *c = (long *)((size_t)rnl + rnickQueryTable[x].off);
00223
00224 p->fWriteLn("OK QUERY OBJECT RNICK=%s %sx %ld", rnl->nick,
00225 rnickQueryTable[x].field, *c);
00226 return 1;
00227 }
00228
00229 int queryRnickUint(RegNickList *rnl, IpcConnectType *p, parse_t *pb, int x)
00230 {
00231 u_int *c = (u_int *)((size_t)rnl + rnickQueryTable[x].off);
00232
00233 p->fWriteLn("OK QUERY OBJECT RNICK=%s %sx %ld", rnl->nick,
00234 rnickQueryTable[x].field, *c);
00235 return 1;
00236 }
00237
00238 int queryRnickUchar(RegNickList *rnl, IpcConnectType *p, parse_t *pb, int x)
00239 {
00240 u_char *c = (u_char *)((size_t)rnl + rnickQueryTable[x].off);
00241
00242 p->fWriteLn("OK QUERY OBJECT RNICK=%s %sx %ld", rnl->nick,
00243 rnickQueryTable[x].field, *c);
00244 return 1;
00245 }
00246
00247 int queryRnickTime(RegNickList *rnl, IpcConnectType *p, parse_t *pb, int x)
00248 {
00249 time_t *c = (time_t *)((size_t)rnl + rnickQueryTable[x].off);
00250
00251 p->fWriteLn("OK QUERY OBJECT RNICK=%s %sx %ld", rnl->nick,
00252 rnickQueryTable[x].field, *c);
00253 return 1;
00254 }
00255
00256 int alterRnickStringD(RegNickList *rnl, IpcConnectType *p, parse_t *pb, int x)
00257 {
00258 char *c = *(char **)((size_t)rnl + rnickQueryTable[x].off);
00259 char *d = parse_getarg(pb);
00260
00261 if (c)
00262 free(c);
00263 c = (char *)0;
00264
00265 if (d != NULL) {
00266 c = str_dup(d);
00267 }
00268 *(char **)((size_t)rnl + rnickQueryTable[x].off) = c;
00269
00270 p->fWriteLn("OK ALTER OBJECT RNICK=%s %sx %s", rnl->nick,
00271 rnickQueryTable[x].field, c);
00272 return 1;
00273 }
00274
00275 int alterRnickEmail(RegNickList *rnl, IpcConnectType *p, parse_t *pb, int x)
00276 {
00277 char *e = parse_getarg(pb);
00278
00279 if (e == NULL)
00280 return 0;
00281 strncpyzt(rnl->email, e, EMAILLEN);
00282
00283 p->fWriteLn("OK ALTER OBJECT RNICK=%s %sx %s", rnl->nick,
00284 rnickQueryTable[x].field, e);
00285 return 1;
00286 }
00287
00288 int alterRnickFlag(RegNickList *rnl, IpcConnectType *p, parse_t *pb, int x)
00289 {
00290 flag_t *c = (flag_t *)((size_t)rnl + rnickQueryTable[x].off);
00291 char *d = parse_getarg(pb);
00292
00293 if (d == NULL) return 0;
00294
00295 *c = atol(d);
00296
00297 p->fWriteLn("OK ALTER OBJECT RNICK=%s %sx %ld", rnl->nick,
00298 rnickQueryTable[x].field, *c);
00299 return 1;
00300 }
00301
00302 int alterRnickLong(RegNickList *rnl, IpcConnectType *p, parse_t *pb, int x)
00303 {
00304 long *c = (long *)((size_t)rnl + rnickQueryTable[x].off);
00305 char *d = parse_getarg(pb);
00306
00307 if (d == NULL) return 0;
00308
00309 *c = atol(d);
00310
00311 p->fWriteLn("OK ALTER OBJECT RNICK=%s %sx %ld", rnl->nick,
00312 rnickQueryTable[x].field, *c);
00313 return 1;
00314 }
00315
00316 int alterRnickUint(RegNickList *rnl, IpcConnectType *p, parse_t *pb, int x)
00317 {
00318 u_int *c = (u_int *)((size_t)rnl + rnickQueryTable[x].off);
00319 char *d = parse_getarg(pb);
00320 int j;
00321
00322 if (d == NULL) return 0;
00323
00324 j = atoi(d);
00325
00326 if (j < 0) j = 0;
00327 *c = j;
00328
00329 p->fWriteLn("OK ALTER OBJECT RNICK=%s %sx %ld", rnl->nick,
00330 rnickQueryTable[x].field, *c);
00331 return 1;
00332 }
00333
00334 int alterRnickUchar(RegNickList *rnl, IpcConnectType *p, parse_t *pb, int x)
00335 {
00336 u_char *c = (u_char *)((size_t)rnl + rnickQueryTable[x].off);
00337 char *d = parse_getarg(pb);
00338 int X;
00339
00340 if (d == 0) return 0;
00341 X = MIN(UCHAR_MAX, MAX(0, atoi(d)));
00342 *c = X;
00343
00344 p->fWriteLn("OK QUERY OBJECT RNICK=%s %sx %ld", rnl->nick,
00345 rnickQueryTable[x].field, *c);
00346 return 1;
00347 }
00348
00349 int alterRnickTime(RegNickList *rnl, IpcConnectType *p, parse_t *pb, int x)
00350 {
00351 time_t *c = (time_t *)((size_t)rnl + rnickQueryTable[x].off);
00352 char *d = parse_getarg(pb);
00353 time_t e;
00354
00355 if (d == 0) return 0;
00356 e = atol(d);
00357 *c = e;
00358
00359 p->fWriteLn("OK QUERY OBJECT RNICK=%s %sx %ld", rnl->nick,
00360 rnickQueryTable[x].field, *c);
00361 return 1;
00362 }
00363
00364
00368 int
00369 IpcType::alterRegNickMessage(RegNickList *rnl, const char *req, IpcConnectType *p, parse_t *pb)
00370 {
00371 char *buf;
00372 int i = 0;
00373
00374 if (req == NULL)
00375 req = "<unknown>";
00376
00377 if (rnl == NULL)
00378 return 0;
00379
00380 if (p->CheckPriv(0, OPRIV_OWNER) && !(p->GetPriv() & PRIV_ALTER_RNICK_GEN)) {
00381 p->fWriteLn("ERR-NOPRIV ALTER OBJECT RNICK=%s %s "
00382 "- User %s Not authorized to alter RNICK %s.",
00383 rnl->nick, req, p->user, req);
00384 return 1;
00385 }
00386
00387 for(i = 0; rnickQueryTable[i].field; i++) {
00388 if (strcmp(req, rnickQueryTable[i].field) == 0) {
00389 if ((rnickQueryTable[i].a_priv && (p->GetPriv() & rnickQueryTable[i].a_priv) != rnickQueryTable[i].a_priv)
00390 || (rnickQueryTable[i].a_priv & PRIV_UNDEF))
00391 {
00392 p->fWriteLn("ERR-NOPRIV QUERY OBJECT RNICK=%s %s"
00393 "- User %s Not authorized to alter RNICK %s.",
00394 rnl->nick, p->user, req, req);
00395 return 1;
00396 }
00397 break;
00398 }
00399 }
00400
00401 if (strcmp(req, "PASS") == 0) {
00402 buf = parse_getarg(pb);
00403
00404 if (p->CheckPriv(0, OPRIV_SETPASS))
00405 {
00406 p->fWriteLn("ERR-NOPERM ALTER OBJECT RNICK=%s PASS - Not authorized.", rnl->nick);
00407 return 1;
00408 }
00409
00410 if (buf == 0 || *buf == '\0' || str_cmp(buf, rnl->nick) == 0)
00411 {
00412 p->fWriteLn("ERR-SYNTAX ALTER OBJECT RNICK=%s PASS - You need to specify a valid password", rnl->nick);
00413 return 1;
00414 }
00415
00416 pw_enter_password(buf, rnl->password, NickGetEnc(rnl));
00417 p->fWriteLn("OK ALTER OBJECT RNICK=%s PASS %s", rnl->nick, buf);
00418 rnl->flags &= ~NFORCEXFER;
00419 rnl->chpw_key = 0;
00420 return 1;
00421 }
00422
00423 if (rnickQueryTable[i].field)
00424 return (* rnickQueryTable[i].a_func)(rnl, p, pb, i);
00425 return 0;
00426 }
00427
00431 int
00432 IpcType::queryRegNickMessage(RegNickList *rnl, const char *req, IpcConnectType *p, parse_t *pb)
00433 {
00434 int i = 0;
00435
00436 if (req == NULL)
00437 req = "<unknown>";
00438
00439 if (rnl == NULL)
00440 return 0;
00441
00442 if (!(p->GetPriv() & PRIV_QUERY_NICK_PUBLIC)) {
00443 p->fWriteLn("ERR-NOPRIV QUERY OBJECT RNICK=%s %s "
00444 "- User %s Not authorized to query RNICK %s.",
00445 rnl->nick, req, p->user, req);
00446 return 1;
00447 }
00448
00449 for(i = 0; rnickQueryTable[i].field; i++) {
00450 if (strcmp(req, rnickQueryTable[i].field) == 0) {
00451 if (rnickQueryTable[i].priv && (p->GetPriv() & rnickQueryTable[i].priv) != rnickQueryTable[i].priv)
00452 {
00453 p->fWriteLn("ERR-NOPRIV QUERY OBJECT RNICK=%s %s"
00454 "- User %s Not authorized to query RNICK %s.",
00455 rnl->nick, p->user, req, req);
00456 return 1;
00457 }
00458 break;
00459 }
00460 }
00461
00462 if (rnickQueryTable[i].field)
00463 return (* rnickQueryTable[i].func)(rnl, p, pb, i);
00464
00465 if (strcmp(req, "LAST-TIME") == 0) {
00466 p->fWriteLn("OK QUERY OBJECT RNICK=%s LAST-TIME %ld", rnl->nick,
00467 rnl->timestamp);
00468 return 1;
00469 }
00470 else if (strcmp(req, "REG-TIME") == 0) {
00471 p->fWriteLn("OK QUERY OBJECT RNICK=%s REG-TIME %ld", rnl->nick,
00472 rnl->timereg);
00473 return 1;
00474 }
00475 else if (strcmp(req, "ACC") == 0) {
00476 UserList* ul = getNickData(rnl->nick);
00477 int acc = 0;
00478
00479 if (ul) {
00480 acc = ul->caccess > 1 ? ul->caccess : 1;
00481 }
00482
00483 p->fWriteLn("OK QUERY OBJECT RNICK=%s ACC %ld", rnl->nick,
00484 acc);
00485 return 1;
00486 }
00487 else if (strcmp(req, "MARK") == 0) {
00488 if (!(p->GetPriv() & PRIV_QUERY_NICK_PUBLIC)) {
00489 p->fWriteLn("ERR-NOPRIV QUERY OBJECT RNICK=%s %s "
00490 "- User %s Not authorized to query RNICK %s.",
00491 rnl->nick, req, p->user, req);
00492 return 1;
00493 }
00494 if (rnl->flags & NMARK)
00495 p->fWriteLn("OK QUERY OBJECT RNICK=%s MARK YES %s", rnl->nick,
00496 rnl->markby ? rnl->markby : "*");
00497 else
00498 p->fWriteLn("OK QUERY OBJECT RNICK=%s MARK NO", rnl->nick);
00499 return 1;
00500 }
00501 else if (strcmp(req, "LAST-HOST") == 0) {
00502 if (rnl->flags & NDBISMASK)
00503 p->fWriteLn("OK QUERY OBJECT RNICK=%s LAST-HOST %s", rnl->nick,
00504 genHostMask(rnl->host));
00505 else
00506 p->fWriteLn("OK QUERY OBJECT RNICK=%s LAST-HOST %s", rnl->nick,
00507 rnl->host);
00508 return 1;
00509 }
00510 else if (strncmp(req, "ACCESS-", 7) == 0) {
00511 int n = atoi(req + 7), o;
00512 nAccessList *acl = NULL;
00513
00514 if ((isdigit(req[7]) && (n < (int)rnl->amasks+1)) || req[7] == '*')
00515 {
00516 acl = LIST_FIRST(&rnl->acl);
00517
00518 if (strcmp(req, "ACCESS-*") == 0) {
00519 p->fWriteLn("OK QUERY OBJECT RNICK=%s ACCESS-* START",
00520 rnl->nick);
00521 for( ; acl != NULL ; acl = LIST_NEXT(acl, al_lst) )
00522 p->fWriteLn("DATA RNICK=%s ACCESS-* %s",
00523 rnl->nick, acl->mask);
00524 p->fWriteLn("OK QUERY OBJECT RNICK=%s ACCESS-* DONE",
00525 rnl->nick);
00526 return 1;
00527 }
00528
00529 if (acl != NULL)
00530 {
00531 for( o = 0; acl ; acl = LIST_NEXT(acl, al_lst) )
00532 if (o++ == n)
00533 break;
00534 }
00535 }
00536
00537 if (acl == NULL)
00538 p->fWriteLn("ERR-NOENTRY QUERY OBJECT RNICK=%s ACCESS-%d - Invalid access item",
00539 rnl->nick, n);
00540 else {
00541
00542 p->fWriteLn("OK QUERY OBJECT RNICK=%s ACCESS-%d %s",
00543 rnl->nick, n, acl->mask);
00544 }
00545 return 1;
00546 }
00547 return 0;
00548 }
00549
00550
00551
00557 int doNonBlock(int listenDesc)
00558 {
00559 int optionValue;
00560
00561 #ifdef SYSV
00562 optionValue = 1;
00563
00564 if (ioctl(listenDesc, FIONBIO, &optionValue) < 0)
00565 return -1;
00566 #else
00567 if ((optionValue = fcntl(listenDesc, F_GETFL, 0)) == -1)
00568 return -1;
00569 #ifdef O_NONBLOCK
00570 if (fcntl(listenDesc, F_SETFL, optionValue | O_NONBLOCK) == -1)
00571 #else
00572 if (fcntl(listenDesc, F_SETFL, optionValue | O_NDELAY) == -1)
00573 #endif
00574 return -1;
00575 #endif
00576 return 0;
00577 }
00578
00584 int
00585 IpcType::start(int portNum)
00586 {
00587 struct sockaddr_in sa;
00588 int reuseAddr;
00589
00590 listenDesc = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
00591
00592 if (portNum == 0)
00593 return -1;
00594
00595 if (listenDesc < 0) {
00596 perror("socket");
00597 return -1;
00598 }
00599
00600 bzero(&sa, sizeof(sa));
00601 sa.sin_port = htons(portNum);
00602 sa.sin_addr.s_addr = 0x100007f;
00603 sa.sin_family = AF_INET;
00604
00605 reuseAddr = 1;
00606 setsockopt(listenDesc, SOL_SOCKET, SO_REUSEADDR, &reuseAddr, sizeof(int));
00607
00608 doNonBlock(listenDesc);
00609
00610 if (bind(listenDesc, (struct sockaddr *) &sa, sizeof(struct sockaddr_in)) < 0) {
00611 perror("bind");
00612 return -1;
00613 }
00614
00615 if ( listen(listenDesc, 5) < 0 ) {
00616 perror("listen");
00617 return -1;
00618 }
00619
00620 topFd = listenDesc;
00621
00622 return 0;
00623 }
00624
00630 void
00631 IpcType::fdFillSet(fd_set & fset)
00632 {
00633 IpcConnectType *pConnect;
00634
00635 if (listenDesc == -1)
00636 return;
00637
00638 FD_SET(listenDesc, &fset);
00639
00640 for (pConnect = links; pConnect; pConnect = pConnect->next) {
00641 if (pConnect->fd != -1) {
00642 FD_SET(pConnect->fd, &fset);
00643 }
00644 }
00645 }
00646
00647
00652 void
00653 IpcType::addCon(IpcConnectType *p)
00654 {
00655 p->next = links;
00656 links = p;
00657 }
00658
00663 void
00664 IpcType::delCon(IpcConnectType *zap)
00665 {
00666 IpcConnectType *p, *p_next, *tmp;
00667
00668 tmp = NULL;
00669
00670 for(p = links; p; p = p_next)
00671 {
00672 p_next = p->next;
00673
00674 if (zap == p)
00675 {
00676 if (tmp)
00677 tmp->next = p->next;
00678 else
00679 links = p->next;
00680 break;
00681 }
00682 else
00683 tmp = p;
00684 }
00685
00686 topFd = listenDesc;
00687
00688 for(p = links; p; p = p->next)
00689 if (p->fd > topFd)
00690 topFd = p->fd;
00691 }
00692
00696 void
00697 IpcType::freeCon(IpcConnectType *zap)
00698 {
00699 zap->buf.empty();
00700 free(zap);
00701
00702 if (zap->user)
00703 free(zap->user);
00704 if (zap->pass)
00705 free(zap->pass);
00706 if (zap->objName)
00707 free(zap->objName);
00708 if (zap->objPass)
00709 free(zap->objPass);
00710 }
00711
00719 int
00720 IpcType::ReadPackets(IpcConnectType *ptrLink)
00721 {
00722 char sockbuf[8192+1], *b;
00723 int k, kt = 0, msgl;
00724
00725
00726 k = read(ptrLink->fd, sockbuf, 8191);
00727
00728
00729
00730
00731
00732 while(k > 0)
00733 {
00734 kt += k;
00735 b = ptrLink->buf.shove(sockbuf, k, &msgl);
00736
00737 if (b && *b) {
00738
00739 strncpyzt(sockbuf, b, msgl);
00740
00741
00742 if (msgl >= IPCBUFSIZE || msgl >= 8000)
00743 return -1;
00744
00745 k = read(ptrLink->fd, sockbuf + msgl, 8191 - msgl);
00746 if (k > 0)
00747 k += msgl;
00748 }
00749 else {
00750 k = read(ptrLink->fd, sockbuf, 8191);
00751 }
00752 }
00753
00754 if (k == 0)
00755 return -1;
00756 if (k == -1) {
00757 if (errno == EINTR || errno == EWOULDBLOCK)
00758 return 0;
00759 return -1;
00760 }
00761 return 0;
00762 }
00763
00774 void
00775 IpcType::pollAndHandle(fd_set &readme, fd_set &writeme, fd_set &xcept)
00776 {
00777 IpcConnectType *p, *p_next;
00778 char *c;
00779
00780 if (listenDesc == -1)
00781 return;
00782
00783 if (FD_ISSET(listenDesc, &readme))
00784 {
00785 struct sockaddr_in sai;
00786 socklen_t alen;
00787 int pFd, ipOk;
00788
00789 if ((pFd = accept(listenDesc, (struct sockaddr *)&sai, &alen)) != -1)
00790 {
00791 ipOk = 1;
00792
00793
00794
00795
00796 if (doNonBlock(pFd) != -1 && ipOk)
00797 {
00798 if (pFd > topFd)
00799 topFd = pFd;
00800 p = (IpcConnectType *)oalloc(sizeof(IpcConnectType));
00801 p->objType = SIPC_UNDEF;
00802 addCon(p);
00803 p->fd = pFd;
00804 p->addr = sai.sin_addr;
00805 }
00806 else
00807 close(pFd);
00808 }
00809 }
00810
00811
00812 for(p = links; p; p = p_next)
00813 {
00814 p_next = p->next;
00815
00816 if (FD_ISSET(p->fd, &xcept)) {
00817 FD_CLR(p->fd, &xcept);
00818 close(p->fd);
00819 delCon(p);
00820 freeCon(p);
00821 continue;
00822 }
00823
00824 if (FD_ISSET(p->fd, &readme)) {
00825 char buf[IPCBUFSIZE];
00826
00827 if (ReadPackets(p) < 0)
00828 {
00829 close(p->fd);
00830 delCon(p);
00831 freeCon(p);
00832 continue;
00833 }
00834
00835 while (p->buf.pop(buf)) {
00836 parse_t pb;
00837
00838 parse_init(&pb, buf);
00839
00840 c = parse_getarg(&pb);
00841 if (c == NULL)
00842 continue;
00843
00844 if (strcmp(c, "AUTH") == 0) {
00845 authMessage(p, &pb);
00846 }
00847 else if (strcmp(c, "QUIT") == 0) {
00848 p->sWrite("OK QUIT\n");
00849 close(p->fd);
00850 p->fd = -1;
00851 }
00852 else if (strcmp(c, "HELP") == 0) {
00853 p->sWrite("OK HELP\n");
00854 p->sWrite("REPLY HELP - Commands: \n");
00855 p->sWrite("REPLY HELP - AUTH HELP QUERY MAKE QUIT \n");
00856 }
00857 else if (p->user == NULL || p->pass == NULL) {
00858 p->fWriteLn("ERR-NOAUTH %s - You are "
00859 "not authenticated. ",
00860 "(Allowed: AUTH, HELP, QUIT)", buf);
00861 }
00862 else if (strcmp(c, "QUERY") == 0) {
00863 queryMessage(p, &pb);
00864 }
00865 else if (strcmp(c, "ALTER") == 0) {
00866 alterMessage(p, &pb);
00867 }
00868 else if (strcmp(c, "LOG") == 0) {
00869 logMessage(p, &pb);
00870 }
00871 else if (strcmp(c, "MAKE") == 0) {
00872 makeMessage(p, &pb);
00873 }
00874 }
00875
00876 if (p->fd == -1) {
00877 delCon(p);
00878 freeCon(p);
00879 continue;
00880 }
00881 }
00882
00883 if (FD_ISSET(p->fd, &writeme)) {
00884 FD_CLR(p->fd, &writeme);
00885
00886 if (p->s == 0) {
00887 char bufs[IPCBUFSIZE];
00888
00889 snprintf(
00890 bufs, sizeof(bufs),
00891 "HELO IAM %s\n"
00892 "AUTH SYSTEM PID %d\n"
00893 "AUTH SYSTEM LOGIN irc/services\n",
00894 myname, getpid()
00895 );
00896 p->sWrite(bufs);
00897 p->s = 1;
00898 }
00899 }
00900 }
00901 }
00902
00906 void
00907 IpcType::authMessage(IpcConnectType *p, parse_t *pb)
00908 {
00909 char *buf = parse_getarg(pb);
00910
00911 if (buf == NULL)
00912 return;
00913
00914 if (!strcmp(buf, "SYSTEM")) {
00915 authSysMessage(p, pb);
00916 }
00917 else if (!strcmp(buf, "OBJECT")) {
00918 authObjMessage(p, pb);
00919 }
00920 else {
00921 p->sWrite("ERR-BADTYPE AUTH - No such auth type\n");
00922 }
00923 }
00924
00928 void
00929 IpcType::queryMessage(IpcConnectType *p, parse_t *pb)
00930 {
00931 char *buf = parse_getarg(pb);
00932
00933 if (buf == NULL)
00934 return;
00935
00936 if (p->user == NULL) {
00937 p->sWrite("ERR-AUTH QUERY - Must authenticate to system\n");
00938 return;
00939 }
00940
00941 if (!strcmp(buf, "SYSTEM")) {
00942 querySysMessage(p, pb);
00943 }
00944 else if (!strcmp(buf, "OBJECT")) {
00945 queryObjMessage(p, pb);
00946 }
00947 else {
00948 p->sWrite("ERR-BADTYPE QUERY - No such query type\n");
00949 }
00950 }
00951
00952
00956 void
00957 IpcType::logMessage(IpcConnectType *p, parse_t *pb)
00958 {
00959 char *service = parse_getarg(pb);
00960 int use_globops=0;
00961 interp::commands::services_cmd_id logt;
00962 SLogfile* logf;
00963
00964
00965 if (service == NULL) {
00966 p->sWrite("ERR-AUTH ALTER - Must at least specify SERVICE - MESSAGE\n");
00967 return;
00968 }
00969
00970 if (p->CheckPriv(PRIV_LOGW, 0)) {
00971 p->fWriteLn("LOG %s "
00972 "- User %s does not have log writing access.",
00973 service, p->user);
00974 return;
00975 }
00976
00977 char* buf;
00978
00979 while ( 1 ) {
00980 buf = parse_getarg(pb);
00981
00982 if (buf == NULL) {
00983 p->sWrite("ERR-AUTH ALTER - Must specify a service, hyphen, message\n");
00984 return;
00985 }
00986 if (*buf == '-') {
00987 buf = parse_getallargs(pb);
00988 break;
00989 }
00990 if (!strcasecmp(buf, "GLOBOPS"))
00991 use_globops=1;
00992 }
00993
00994 if (buf == NULL) {
00995 p->sWrite("ERR-AUTH ALTER - Must specify a service, hyphen, message\n");
00996 return;
00997 }
00998
00999 if (!strcasecmp(service, "ChanServ")) {
01000 logt = CSE_IPC;
01001 logf = chanlog;
01002 }
01003 else if (!strcasecmp(service, "NickServ")) {
01004 logt = NSE_IPC;
01005 logf = nicklog;
01006 }
01007 else {
01008 service = "OperServ";
01009 logt = OSE_IPC;
01010 logf = operlog;
01011 }
01012
01013 sSend(":%s GLOBOPS :(IPC:%s) %s", service, p->user, buf);
01014 logf->log(NULL, logt, NULL, 0, "(IPC:%s,%s) %s", p->user,service, buf);
01015 }
01016
01020 void
01021 IpcType::alterMessage(IpcConnectType *p, parse_t *pb)
01022 {
01023 char *buf = parse_getarg(pb);
01024
01025 if (buf == NULL) {
01026 p->sWrite("ERR-AUTH ALTER - Must specify target and type\n");
01027 return;
01028 }
01029
01030 if (p->user == NULL) {
01031 p->sWrite("ERR-AUTH ALTER - Must authenticate to system\n");
01032 return;
01033 }
01034
01035
01036
01037
01038 if (!strcmp(buf, "OBJECT")) {
01039 alterObjMessage(p, pb);
01040 }
01041 else {
01042 p->sWrite("ERR-BADTYPE QUERY - No such query type\n");
01043 }
01044 }
01045
01049 void
01050 IpcType::authSysMessage(IpcConnectType *p, parse_t *pb)
01051 {
01052 char *str_dup(const char *);
01053 char *buf = parse_getarg(pb);
01054 const ssUInfo *q;
01055 char authBuf[IRCBUF];
01056 int valid = 0;
01057
01058 if (buf == NULL)
01059 return;
01060
01061 if (!strcmp(buf, "LOGIN")) {
01062
01063 buf = parse_getarg(pb);
01064
01065 if (buf == NULL) {
01066 p->sWrite("ERR-BADLOGIN AUTH SYSTEM LOGIN - Invalid login\n");
01067 return;
01068 }
01069
01070 if ((q = getServicesSysUser(buf))) {
01071 valid = 1;
01072 if (p->user)
01073 free(p->user);
01074 p->user = str_dup(buf);
01075 p->gpriv = 0;
01076 p->opriv = 0;
01077 }
01078
01079
01080
01081
01082
01083 p->cookie = lrand48();
01084
01085 p->fWriteLn("OK AUTH SYSTEM LOGIN");
01086 p->fWriteLn("AUTH COOKIE %X%X", p->fd, p->cookie);
01087 return;
01088 }
01089 else if (!strcmp(buf, "PASS")) {
01090 unsigned char digest[16], *pBuf;
01091 MD5Context ctx;
01092
01093 buf = parse_getarg(pb);
01094
01095 if (buf == NULL || (p->user) == NULL || (q = getServicesSysUser(p->user)) == NULL) {
01096 p->sWrite("ERR-BADLOGIN AUTH SYSTEM LOGIN - Invalid login\n");
01097 if (p->user)
01098 SetDynBuffer(&p->user, NULL);
01099 return;
01100 }
01101
01102 snprintf(authBuf, sizeof(authBuf), "%X%X:%s", p->fd, (u_int)p->cookie, q->password);
01103
01104 MD5Init(&ctx);
01105 MD5Update(&ctx, (const u_char *)authBuf, strlen(authBuf));
01106 MD5Final(digest, &ctx);
01107
01108 pBuf = (u_char *)str_dup(md5_printable(digest));
01109
01110 if (pBuf == NULL || p == NULL) {
01111 p->sWrite("ERR-BADLOGIN AUTH SYSTEM LOGIN - Internal Failure\n");
01112 if (p->user)
01113 SetDynBuffer(&p->user, NULL);
01114 return;
01115 }
01116
01117 if (strcmp((char *)pBuf, buf)) {
01118 p->sWrite("ERR-BADLOGIN AUTH SYSTEM LOGIN - Invalid login\n");
01119 if (p->user)
01120 SetDynBuffer(&p->user, NULL);
01121 return;
01122 }
01123
01124 p->fWriteLn("OK AUTH SYSTEM PASS");
01125 p->fWriteLn("YOU ARE %s", p->user);
01126 p->pass = (char *)pBuf;
01127 p->gpriv = q->priv;
01128
01129 if ((p->gpriv & PRIV_NOWNER_EQUIV))
01130 p->opriv |= OPRIV_OWNER;
01131 else
01132 p->opriv = 0;
01133
01134 return;
01135 }
01136
01137 p->fWriteLn("ERR-BADTYPE AUT SYSTEMH");
01138 }
01139
01143 void
01144 IpcType::authObjMessage(IpcConnectType *p, parse_t *pb)
01145 {
01146 char *str_dup(const char *);
01147 char *buf = parse_getarg(pb), *buf1, *buf2, *pawd = 0, *objStr = 0;
01148 RegNickList *rnl;
01149 RegChanList *rcl;
01150
01151 char authBuf[IRCBUF];
01152 int valid = 0;
01153
01154 if (p->objType == SIPC_RNICK)
01155 objStr = "RNICK";
01156 else if (p->objType == SIPC_RCHAN)
01157 objStr = "RCHAN";
01158 else objStr = "<Undef>";
01159
01160 if (buf == NULL)
01161 return;
01162
01163 if (!strcmp(buf, "LOGIN"))
01164 {
01165
01166 buf1 = parse_getarg(pb);
01167 buf2 = parse_getarg(pb);
01168
01169 objStr = buf1;
01170
01171 if (buf1 == NULL || buf2 == NULL) {
01172 p->fWriteLn("ERR-BADLOGIN AUTH OBJECT LOGIN%s%s - Invalid login", objStr ? " " : "", objStr ? objStr : "");
01173 return;
01174 }
01175
01176 if (!str_cmp(buf1, "RNICK") && (rnl = getRegNickData(buf2)))
01177 {
01178 p->opriv = 0;
01179 valid = 1;
01180
01181 if (p->CheckPriv(PRIV_RNICK_LOGIN, 0))
01182 valid = 0;
01183
01184 if (p->objName)
01185 free(p->objName);
01186 if (valid) {
01187 p->objName = str_dup(buf2);
01188 p->objType = SIPC_RNICK;
01189 }
01190 }
01191 else if (!str_cmp(buf1, "RCHAN") && (rcl = getRegChanData(buf2)))
01192 {
01193 p->opriv = 0;
01194 valid = 1;
01195
01196 if (p->CheckPriv(PRIV_RCHAN_LOGIN, 0))
01197 valid = 0;
01198
01199 if (p->objName)
01200 free(p->objName);
01201 if (valid) {
01202 p->objName = str_dup(buf2);
01203 p->objType = SIPC_RCHAN;
01204 }
01205 }
01206
01207
01208 p->cookie = lrand48();
01209 p->fWriteLn("OK AUTH OBJECT %s LOGIN", objStr);
01210 p->fWriteLn("AUTH COOKIE %X%X", p->fd, p->cookie);
01211 return;
01212 }
01213 else if (!strcmp(buf, "CHPASSKEY"))
01214 {
01215 buf1 = parse_getarg(pb);
01216
01217 if (buf1 && p->objType == SIPC_RNICK && p->objName)
01218 {
01219 rnl = getRegNickData(p->objName);
01220
01221 if (rnl && rnl->chpw_key)
01222 {
01223 const char *rnE = rnl->email;
01224 const char *rnP = PrintPass(rnl->password, NickGetEnc(rnl));
01225 const char *pwAuthChKey;
01226
01227 if (rnl->flags & NFORCEXFER)
01228 rnE = "-forced-transfer-";
01229 pwAuthChKey = GetAuthChKey(rnE, rnP,
01230 rnl->timereg, rnl->chpw_key);
01231 if (strcmp(pwAuthChKey, buf1) == 0) {
01232 p->objPass = str_dup("");
01233 p->opriv = OPRIV_SETPASS;
01234 p->fWriteLn("OK AUTH OBJECT SETPASS");
01235 return;
01236 }
01237 }
01238 }
01239
01240 if (buf1 && p->objType == SIPC_RCHAN && p->objName)
01241 {
01242 rcl = getRegChanData(p->objName);
01243
01244 if (rcl && rcl->chpw_key && (rnl = rcl->founderId.getNickItem()))
01245 {
01246 const char *rcE = rnl->email;
01247 const char *rcP = PrintPass(rcl->password, ChanGetEnc(rcl));
01248 const char *pwAuthChKey;
01249
01250 if (rcl->flags & CFORCEXFER)
01251 rcE = "-forced-transfer-";
01252 pwAuthChKey = GetAuthChKey(rcE, rcP,
01253 rcl->timereg, rcl->chpw_key);
01254 if (strcmp(pwAuthChKey, buf1) == 0) {
01255 p->objPass = str_dup("");
01256 p->opriv = OPRIV_SETPASS;
01257 p->fWriteLn("OK AUTH OBJECT SETPASS");
01258 return;
01259 }
01260 }
01261 }
01262
01263 p->fWriteLn("ERR-BADLOGIN AUTH OBJECT %s LOGIN - Internal Failure",
01264 objStr);
01265 if (p->objName)
01266 SetDynBuffer(&p->objName, NULL);
01267 }
01268 else if (!strcmp(buf, "PASS"))
01269 {
01270 unsigned char digest[16], *pBuf;
01271 MD5Context ctx;
01272 int valid = 0;
01273
01274 buf = parse_getarg(pb);
01275
01276 if (p->objType == SIPC_RNICK)
01277 objStr = "RNICK";
01278 else if (p->objType == SIPC_RCHAN)
01279 objStr = "RCHAN";
01280 else objStr = "<Undef>";
01281
01282 if (objStr == 0) {
01283 p->fWriteLn("ERR-BADLOGIN AUTH OBJECT %s LOGIN - Invalid login", objStr);
01284 if (p->objName)
01285 SetDynBuffer(&p->objName, NULL);
01286 return;
01287 }
01288
01289 if (buf && p->objType == SIPC_RNICK && p->objName &&
01290 (rnl = getRegNickData(p->objName)))
01291 {
01292 valid = 1;
01293 if (rnl->flags & NENCRYPT)
01294 pawd = md5_printable(rnl->password);
01295 else
01296 pawd = md5_printable(md5_password(rnl->password));
01297 }
01298 else if (buf && p->objType == SIPC_RCHAN && p->objName &&
01299 (rcl = getRegChanData(p->objName)))
01300 {
01301 valid = 1;
01302 if (rcl->flags & CENCRYPT)
01303 pawd = md5_printable(rcl->password);
01304 else
01305 pawd = md5_printable(md5_password(rcl->password));
01306 }
01307 else {
01308 p->fWriteLn("ERR-BADLOGIN AUTH OBJECT %s LOGIN - Invalid login", objStr);
01309 if (p->objName)
01310 SetDynBuffer(&p->objName, NULL);
01311 return;
01312 }
01313
01314 snprintf(authBuf, sizeof(authBuf), "%X%X:%s", p->fd, (u_int)p->cookie, pawd);
01315
01316 MD5Init(&ctx);
01317 MD5Update(&ctx, (const u_char *)authBuf, strlen(authBuf));
01318 MD5Final(digest, &ctx);
01319
01320 pBuf = (u_char *)str_dup(md5_printable(digest));
01321
01322 if (pBuf == NULL || p == NULL) {
01323 p->fWriteLn("ERR-BADLOGIN AUTH OBJECT %s LOGIN - Internal Failure",
01324 objStr);
01325 if (p->objName)
01326 SetDynBuffer(&p->objName, NULL);
01327 return;
01328 }
01329
01330 if (strcmp((char *)pBuf, buf)) {
01331 p->fWriteLn("ERR-BADLOGIN AUTH OBJECT %s LOGIN - Invalid login", objStr);
01332 if (p->objName)
01333 SetDynBuffer(&p->objName, NULL);
01334 return;
01335 }
01336
01337 p->fWriteLn("OK AUTH OBJECT %s PASS", objStr);
01338
01339 p->objPass = (char *)pBuf;
01340 p->opriv = OPRIV_OWNER;
01341 return;
01342 }
01343
01344 p->fWriteLn("ERR-BADTYPE AUTH OBJET");
01345 }
01346
01347
01351 int isQlined(const char *nick)
01352 {
01353 int i;
01354
01355 const char *forbiddenPatterns[] =
01356 {
01357 "DALnet", "SorceryNet", "Status",
01358 "AUX", "PRN", "LPT?",
01359 "COM?", "K9", "W",
01360 "X", "NoteOp", "OperOp",
01361 "ChanOp", "NickOp", "*Serv",
01362 "HelpServ", "*He*p*S*rv*", "ChanServ",
01363 "*Ch*n*S*rv*", "NickServ", "*Ni*k*S*rv*",
01364 "MemoServ", "*Me*o*S*rv*", "OperServ",
01365 "*Op*r*S*rv*", "Warlock", "ServOp",
01366 "Sorcery*", "IRCop", "*IRC*op*",
01367 "kline", "Services", "admin*",
01368 "ms", "ns", "cs",
01369 "os",
01370 "ServBot", "ChannelBot", "*net*admin*",
01371 "Auth-*",
01372 NULL
01373 };
01374
01375 for(i = 0; forbiddenPatterns[i]; i++)
01376 if (match(forbiddenPatterns[i], nick) == 0)
01377 return 1;
01378 return 0;
01379 }
01380
01384 void
01385 IpcType::makeMessage(IpcConnectType *p, parse_t *pb)
01386 {
01387 char pwStuff[PASSLEN + 1];
01388 char *buf = parse_getarg(pb);
01389
01390 if (!p->user) {
01391 p->sWrite("ERR-NOTAUTH MAKE - You must be authenticated to make something.\n");
01392 return;
01393 }
01394
01395 if (buf != NULL)
01396 {
01397 if (strcmp(buf, "RCHAN") == 0) {
01398 p->sWrite("ERR-UNIMPLEMENTED MAKE RCHAN - Not yet implemented\n");
01399 }
01400 else if (strcmp(buf, "RNICK") == 0) {
01401 RegNickList *ptrNick;
01402 char *nick = parse_getarg(pb);
01403 char *email = parse_getarg(pb);
01404 char *host = parse_getarg(pb);
01405 char *ptrChar;
01406 int pws;
01407
01408 if (nick == NULL) {
01409 p->fWrite("ERR-NONICK MAKE NICK=%s - Nickname missing\n", nick);
01410 return;
01411 }
01412
01413 if (email == NULL) {
01414 p->fWrite("ERR-NOEMAIL MAKE NICK=%s - Email missing\n", nick);
01415 return;
01416 }
01417
01418 if (host == NULL) {
01419 p->fWrite("ERR-NOEMAIL MAKE NICK=%s - Host address missing\n", nick);
01420 return;
01421 }
01422
01423 if (getNickData(nick)) {
01424 p->fWrite("ERR-NICKINUSE MAKE NICK=%s - Nickname is in use.\n", nick);
01425 return;
01426 }
01427
01428 if (*nick == '\0' || strlen(nick) > NICKLEN || *nick == '-'
01429 || isdigit(*nick)) {
01430 p->fWrite("ERR-NICKINVALID MAKE NICK=%s - Nickname not valid\n", nick);
01431 return;
01432 }
01433
01434 for(ptrChar = nick; *ptrChar; ptrChar++)
01435 {
01436 if (isalnum(*ptrChar))
01437 continue;
01438
01439 if (*ptrChar == '[' || *ptrChar == ']' ||
01440 *ptrChar == '{' || *ptrChar == '}' ||
01441 *ptrChar == '|' || *ptrChar == '_' ||
01442 *ptrChar == '\\' || *ptrChar == '`' ||
01443 *ptrChar == '^')
01444 continue;
01445 p->fWrite("ERR-NICKINVALID MAKE RNICK=%s - Nickname not valid\n", nick);
01446 return;
01447 }
01448
01449 if (isQlined(nick)) {
01450 p->fWrite("ERR-NICKQLINE MAKE RNICK=%s - Nickname reserved.\n", nick);
01451 return;
01452 }
01453
01454 if (getRegNickData(nick)) {
01455 p->fWrite("ERR-NICKINUSE MAKE RNICK=%s - Nickname is in use.\n", nick);
01456 return;
01457 }
01458
01459
01460 ptrNick = (RegNickList *)oalloc(sizeof(RegNickList));
01461 ptrNick->regnum.SetNext(top_regnick_idnum);
01462 strcpy(ptrNick->nick, nick);
01463 strcpy(ptrNick->user, "www-temp");
01464 SetDynBuffer(&ptrNick->host, host);
01465 strncpyzt(ptrNick->email, email, EMAILLEN);
01466 ptrNick->timereg = ptrNick->timestamp = CTime;
01467 ptrNick->amasks = 0;
01468 ptrNick->url = NULL;
01469 ptrNick->chans = 0;
01470 ptrNick->flags = (NDBISMASK);
01471 addRegNick(ptrNick);
01472
01473 pws = lrand48();
01474 snprintf(pwStuff, 16, "%X%X", (u_int)(pws ^ p->cookie), (u_int)(pws ^ startup));
01475 pw_enter_password(pwStuff, ptrNick->password, NickGetEnc(ptrNick));
01476
01477
01478 nicklog->log(NULL, NS_REGISTER, ptrNick->nick, 0, "%s![*ipc*:%s]@%s", ptrNick->nick, p->user, host);
01479 p->fWriteLn("OK MAKE RNICK=%s PASS=%s", nick, pwStuff);
01480 return;
01481 }
01482 }
01483 p->sWrite("ERR-BADTYPE MAKE - Unsupported make type (must be RNICK or RCHAN)\n");
01484 }
01485
01489 void
01490 IpcType::querySysMessage(IpcConnectType *p, parse_t *pb)
01491 {
01492 char *buf = parse_getarg(pb);
01493
01494 if (buf != NULL)
01495 {
01496 if (strcmp(buf, "UPTIME") == 0) {
01497 p->fWriteLn("OK QUERY SYSTEM UPTIME=%ld", time(0) - startup);
01498 return;
01499 }
01500 }
01501 p->sWrite("ERR-BADTYPE QUERY SYSTEM - No such object query type (UPTIME) \n");
01502 }
01504
01508 void
01509 IpcType::queryObjMessage(IpcConnectType *p, parse_t *pb)
01510 {
01511 char *buf = parse_getarg(pb);
01512 int is_ignore = 0, is_ahurt = 0, is_akill = 0;
01513
01514 if (buf != NULL)
01515 {
01516 if (strcmp(buf, "AKILL") == 0)
01517 is_akill = 1;
01518 else if (strcmp(buf, "AHURT") == 0)
01519 is_ahurt = 1;
01520 else if (strcmp(buf, "IGNORE") == 0)
01521 is_ignore = 1;
01522
01523 if (strcmp(buf, "RNICK") == 0)
01524 {
01525 char *req;
01526 RegNickList *rnl;
01527
01528 if ((buf = parse_getarg(pb)) == NULL) {
01529 p->sWrite("ERR-SYNTAX QUERY OBJECT RNICK - nickname/attribute pair missing.\n");
01530 return;
01531 }
01532
01533 req = parse_getarg(pb);
01534
01535 if ((rnl = getRegNickData(buf)) == NULL) {
01536
01537 if (req && strcmp(req, "ISREG"))
01538 p->fWriteLn("ERR-BADTARGET QUERY OBJECT RNICK=%s - NOT_REGISTERED", buf);
01539 else
01540 p->fWriteLn("OK QUERY OBJECT RNICK=%s ISREG=FALSE - Nickname is not registered.", buf);
01541 return;
01542 }
01543
01544 if (req == NULL || strcmp(req, "ISREG") == 0) {
01545 p->fWriteLn("OK QUERY OBJECT RNICK=%s ISREG=TRUE - Nickname is registered.", buf);
01546 return;
01547 }
01548
01549 if (strcmp(req, "ISBYPASS") == 0) {
01550 if (rnl->flags & NBYPASS)
01551 p->fWriteLn("OK QUERY OBJECT RNICK=%s ISBYPASS=TRUE", buf);
01552 else
01553 p->fWriteLn("OK QUERY OBJECT RNICK=%s ISBYPASS=FALSE", buf);
01554 }
01555
01556
01557 if (queryRegNickMessage(rnl, req, p, pb))
01558 return;
01559
01560 p->fWriteLn("ERR-BADATT QUERY OBJECT RNICK EATTR - Known attributes (ISREG, ISBYPASS)");
01561
01562 return;
01563 }
01564 else if (is_akill || is_ahurt || is_ignore) {
01565 const char *tar = parse_getarg(pb), *akstr;
01566
01567 akstr = is_ignore ? "IGNORE" :
01568 is_ahurt ? "AHURT" :
01569 "AKILL";
01570
01571 if (!(p->GetPriv() & PRIV_QUERY_AKILL_LIST)) {
01572 p->fWriteLn("ERR-NOPRIV QUERY OBJECT %s=LIST "
01573 "- User %s Not authorized to query %s.",
01574 akstr, p->user, akstr);
01575 return;
01576 }
01577
01578 if (tar && strcmp(tar, "LIST") == 0)
01579 tar = NULL;
01580
01581
01582 {
01583 p->fWriteLn("START QUERY OBJECT %s=LIST",
01584 akstr);
01585 p->sendAkills(is_ignore ? A_IGNORE : is_ahurt ? A_AHURT : A_AKILL, tar);
01586 p->fWriteLn("OK QUERY OBJECT %s=LIST",
01587 akstr);
01588 }
01589 return;
01590 }
01591 else if (strcmp(buf, "RCHAN") == 0)
01592 {
01593 if ((buf = parse_getarg(pb)) == NULL) {
01594 p->sWrite("ERR-BADSYNTAX QUERY OBJECT RCHAN - channel/attribute pair missing.\n");
01595 return;
01596 }
01597
01598 return;
01599 }
01600 }
01601
01602 p->sWrite("ERR-BADTYPE QUERY OBJECT - No such object query type (RCHAN, RNICK, AKILL, AHURT, IGNORE) \n");
01603 }
01604
01605
01609 void
01610 IpcType::alterObjMessage(IpcConnectType *p, parse_t *pb)
01611 {
01612 char *buf = parse_getarg(pb);
01613
01614
01615 if (buf != NULL)
01616 {
01617
01618
01619
01620
01621
01622
01623
01624 if (strcmp(buf, "RNICK") == 0)
01625 {
01626 char *req;
01627 RegNickList *rnl;
01628
01629 if ((buf = parse_getarg(pb)) == NULL) {
01630 p->sWrite("ERR-SYNTAX QUERY OBJECT RNICK - nickname/attribute pair missing.\n");
01631 return;
01632 }
01633
01634 req = parse_getarg(pb);
01635
01636 if ((rnl = getRegNickData(buf)) == NULL) {
01637 p->fWriteLn("ERR-BADTARGET ALTER OBJECT RNICK=%s - NOT_REGISTERED", buf);
01638 return;
01639 }
01640
01641
01642
01643
01644
01645
01646 if (strcmp(req, "+BYPASS") == 0) {
01647 if (p->CheckPriv(PRIV_SET_BYPASS, 0)) {
01648 p->fWriteLn("ERR-NOPRIV ALTER OBJECT RNICK=%s %s"
01649 "- Not authorized to alter RNICK %s.",
01650 rnl->nick, req, req);
01651 return;
01652 }
01653 p->fWriteLn("OK ALTER OBJECT RNICK=%s ISBYPASS=TRUE", buf);
01654 rnl->flags |= NBYPASS;
01655 }
01656
01657 if (strcmp(req, "-BYPASS") == 0) {
01658 if (p->CheckPriv(PRIV_UNSET_BYPASS, 0)) {
01659 p->fWriteLn("ERR-NOPRIV ALTER OBJECT RNICK=%s %s"
01660 "- Not authorized to alter RNICK %s.",
01661 rnl->nick, req, req);
01662 return;
01663 }
01664 p->fWriteLn("OK ALTER OBJECT RNICK=%s ISBYPASS=FALSE", buf);
01665 rnl->flags &= ~NBYPASS;
01666 }
01667
01668
01669 if (alterRegNickMessage(rnl, req, p, pb))
01670 return;
01671
01672 p->fWriteLn("ERR-BADATT ALTER OBJECT RNICK EATTR - Known attributes (ISREG, ISBYPASS)");
01673
01674 return;
01675 }
01676 else if (strcmp(buf, "RCHAN") == 0)
01677 {
01678 RegChanList *rcl;
01679
01680 if ((buf = parse_getarg(pb)) == NULL) {
01681 p->sWrite("ERR-BADSYNTAX ALTER OBJECT RCHAN - channel/attribute pair missing.\n");
01682 return;
01683 }
01684
01685 rcl = getRegChanData(buf);
01686
01687 if (rcl == NULL) {
01688 p->sWrite("ERR-NOTARGET ALTER OBJECT RCHAN\n");
01689 return;
01690 }
01691
01692 if ((buf = parse_getarg(pb)) == NULL) {
01693 p->sWrite("ERR-BADSYNTAX ALTER OBJECT RCHAN - channel/attribute pair missing.\n");
01694 return;
01695 }
01696
01697 if (strcmp(buf, "PASS") == 0)
01698 {
01699 if ((buf = parse_getarg(pb)) == NULL) {
01700 p->sWrite("ERR-BADSYNTAX ALTER OBJECT RCHAN - attribute value missing.\n");
01701 return;
01702 }
01703
01704 if (p->CheckPriv(0, OPRIV_SETPASS))
01705 {
01706 p->fWriteLn("ERR-NOPERM ALTER OBJECT RCHAN=%s PASS - Not authorized.", rcl->name);
01707 return;
01708 }
01709
01710 if (buf == 0 || *buf == '\0' || str_cmp(buf, rcl->name) == 0)
01711 {
01712 p->fWriteLn("ERR-SYNTAX ALTER OBJECT RCHAN=%s PASS - You need to specify a valid password", rcl->name);
01713 return;
01714 }
01715
01716 pw_enter_password(buf, rcl->password, ChanGetEnc(rcl));
01717 rcl->flags &= ~CFORCEXFER;
01718 rcl->chpw_key = 0;
01719 p->fWriteLn("OK ALTER OBJECT RCHAN=%s PASS %s", rcl->name, buf);
01720 return;
01721 }
01722
01723
01724 return;
01725 }
01726 }
01727
01728 p->sWrite("ERR-BADTYPE QUERY OBJECT - No such object alter type (RNICK) \n");
01729 }
01730
01734 void
01735 IpcConnectType::sWrite(const char *buf)
01736 {
01737 int len, retcode = send(fd, buf, len=strlen(buf), 0);
01738
01739 if (retcode == -1) {
01740 if (errno != EINTR && errno != EWOULDBLOCK &&
01741 errno != EMSGSIZE) {
01742 if (fd != -1)
01743 close(fd);
01744 fd = -1;
01745 }
01746 return;
01747 }
01748 else if (retcode > 0 && retcode < len) {
01749 sWrite(buf + retcode);
01750 }
01751 }
01752
01753 void
01754 IpcConnectType::fWrite(const char *buf, ...)
01755 {
01756 char stuff[IRCBUF];
01757 va_list ap;
01758
01759 va_start(ap, buf);
01760 vsnprintf(stuff, sizeof(stuff), buf, ap);
01761 va_end(ap);
01762
01763 sWrite(stuff);
01764 }
01765
01766 void
01767 IpcConnectType::fWriteLn(const char *buf, ...)
01768 {
01769 char stuff[IRCBUF];
01770 va_list ap;
01771
01772 va_start(ap, buf);
01773 vsnprintf(stuff, sizeof(stuff), buf, ap);
01774 va_end(ap);
01775
01776 send(fd, stuff, strlen(stuff), 0);
01777 send(fd, "\n", 1, 0);
01778 }
01779