static int32_t secmon_auth_client(uchar *ucrc) { uint32_t crc; struct s_auth *account; struct s_client *cur_cl = cur_client(); unsigned char md5tmp[MD5_DIGEST_LENGTH]; if (cur_cl->auth) { int32_t s=memcmp(cur_cl->ucrc, ucrc, 4); if (s) cs_log("wrong user-crc or garbage !?"); return !s; } cur_cl->crypted=1; crc=(ucrc[0]<<24) | (ucrc[1]<<16) | (ucrc[2]<<8) | ucrc[3]; for (account=cfg.account; (account) && (!cur_cl->auth); account=account->next) if ((account->monlvl) && (crc==crc32(0L, MD5((unsigned char *)account->usr, strlen(account->usr), md5tmp), MD5_DIGEST_LENGTH))) { memcpy(cur_cl->ucrc, ucrc, 4); aes_set_key(cur_cl, (char *)MD5((unsigned char *)ESTR(account->pwd), strlen(ESTR(account->pwd)), md5tmp)); if (cs_auth_client(cur_cl, account, NULL)) return -1; cur_cl->auth=1; } if (!cur_cl->auth) { cs_auth_client(cur_cl, (struct s_auth *)0, "invalid user"); return -1; } return cur_cl->auth; }
int main(int argc, char *argv[]) { int opt, ret; char *tempdir; struct stat st; /* argument parsing */ while ((opt = getopt_long(argc, argv, optstring, long_opts, NULL)) != -1) switch (opt) { case 'V': fprintf(stderr, "%s %s\n", NAME, VERSION); return 0; default: fprintf(stderr, "unknown option '%c'", opt); case '?': fputs(help_msg, stderr); exit(1); break; } openlog(NAME, LOG_PERROR, LOG_DAEMON); tempdir = argv[optind]; if (!tempdir) asprintf(&tempdir, "/tmp/%s-%i", NAME, getppid()); /* setup input */ if (fstat(STDIN_FILENO, &st)) mylog(LOG_ERR, "fstat(0): %s", ESTR(errno)); char *dat; dat = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE | MAP_POPULATE, STDIN_FILENO, 0); if (dat == MAP_FAILED) mylog(LOG_ERR, "mmap(0): %s", ESTR(errno)); /* start parsing */ jsmn_parser prs; jsmntok_t *tok; size_t tokcnt; jsmn_init(&prs); ret = jsmn_parse(&prs, dat, st.st_size, NULL, 0); if (ret < 0) mylog(LOG_ERR, "jsmn_parse returned %i", ret); jsmn_init(&prs); tokcnt = ret; tok = malloc(sizeof(*tok)*tokcnt); ret = jsmn_parse(&prs, dat, st.st_size, tok, tokcnt); if (ret < 0) mylog(LOG_ERR, "jsmn_parse returned %i", ret); tokdump(dat, tok, tempdir); return 0; }
static int tokdump(char *str, jsmntok_t *t, const char *fs) { int fd, ntok, j, ret; char *newfs; size_t len; switch (t->type) { case JSMN_PRIMITIVE: case JSMN_STRING: fd = open(fs, O_RDWR | O_CREAT | O_TRUNC, 0666); if (fd < 0) mylog(LOG_ERR, "create %s: %s", fs, ESTR(errno)); ret = write(fd, str+t->start, t->end - t->start); if (ret < 0) mylog(LOG_ERR, "write %s: %s", fs, ESTR(errno)); close(fd); return 1; case JSMN_OBJECT: newfs = NULL; len = 0; ntok = 1; if (mkdir(fs, 0777) < 0) mylog(LOG_ERR, "mkdir %s: %s", fs, ESTR(errno)); for (j = 0; j < t->size; ++j) { if (t[ntok].type != JSMN_STRING) mylog(LOG_ERR, "property with non-string name"); if (strlen(fs) + t[ntok].end - t[ntok].start + 1 > len) { len = (strlen(fs) + t[ntok].end - t[ntok].start + 1 + 128) & ~127; newfs = realloc(newfs, len); if (!newfs) mylog(LOG_ERR, "realloc %li: %s", (long)len, ESTR(errno)); } sprintf(newfs, "%s/%.*s", fs, t[ntok].end - t[ntok].start, str + t[ntok].start); ++ntok; ntok += tokdump(str, t+ntok, newfs); } if (newfs) free(newfs); return ntok; case JSMN_ARRAY: newfs = malloc(strlen(fs) + 16); ntok = 1; if (mkdir(fs, 0777) < 0) mylog(LOG_ERR, "mkdir %s: %s", fs, ESTR(errno)); for (j = 0; j < t->size; ++j) { sprintf(newfs, "%s/%i", fs, j); ntok += tokdump(str, t+ntok, newfs); } free(newfs); return ntok; default: return 0; } }
void cs_reinit_clients(struct s_auth *new_accounts) { struct s_auth *account; unsigned char md5tmp[MD5_DIGEST_LENGTH]; struct s_client *cl; for (cl = first_client->next; cl; cl = cl->next) { if ((cl->typ == 'c' || cl->typ == 'm') && cl->account) { for (account = new_accounts; (account) ; account = account->next) { if (!strcmp(cl->account->usr, account->usr)) break; } if (account && !account->disabled && cl->pcrc == crc32(0L, MD5((uchar *)ESTR(account->pwd), strlen(ESTR(account->pwd)), md5tmp), MD5_DIGEST_LENGTH)) { cl->account = account; if (cl->typ == 'c') { cl->grp = account->grp; cl->aureader_list = account->aureader_list; cl->autoau = account->autoau; cl->expirationdate = account->expirationdate; cl->allowedtimeframe[0] = account->allowedtimeframe[0]; cl->allowedtimeframe[1] = account->allowedtimeframe[1]; cl->ncd_keepalive = account->ncd_keepalive; cl->c35_suppresscmd08 = account->c35_suppresscmd08; cl->tosleep = (60*account->tosleep); cl->c35_sleepsend = account->c35_sleepsend; cl->monlvl = account->monlvl; cl->disabled = account->disabled; cl->fchid = account->fchid; // CHID filters cl->cltab = account->cltab; // Class // newcamd module doesn't like ident reloading if (!cl->ncd_server) cl->ftab = account->ftab; // Ident cl->sidtabs.ok = account->sidtabs.ok; // services cl->sidtabs.no = account->sidtabs.no; // services cl->failban = account->failban; memcpy(&cl->ctab, &account->ctab, sizeof(cl->ctab)); memcpy(&cl->ttab, &account->ttab, sizeof(cl->ttab)); webif_client_reset_lastresponsetime(cl); if (account->uniq) cs_fake_client(cl, account->usr, (account->uniq == 1 || account->uniq == 2) ? account->uniq + 2 : account->uniq, cl->ip); ac_init_client(cl, account); } } else { if (get_module(cl)->type & MOD_CONN_NET) { cs_debug_mask(D_TRACE, "client '%s', thread=%8lX not found in db (or password changed)", cl->account->usr, (unsigned long)cl->thread); kill_thread(cl); } else { cl->account = first_client->account; } } } else { cl->account = NULL; } } }
void system_dump(void){ char *buffer = NULL; //get wan gw buffer = NSTR(primary_wan_ip_set[0].gw_ip); D(SYSTEM, "get apcli0 gw [%s]\n", buffer); //get wan ip buffer = NSTR(primary_wan_ip_set[0].ip); D(SYSTEM, "get apcli0 ip [%s]\n", buffer); //get wan mac buffer = ESTR(SYS_wan_mac); D(SYSTEM, "get apcli0 mac [%s]\n", buffer); update_mat_table(); system_show_assoclist(); }
int32_t cs_auth_client(struct s_client * client, struct s_auth *account, const char *e_txt) { int32_t rc = 0; unsigned char md5tmp[MD5_DIGEST_LENGTH]; char buf[32]; char *t_crypt = "encrypted"; char *t_plain = "plain"; char *t_grant = " granted"; char *t_reject = " rejected"; char *t_msg[] = { buf, "invalid access", "invalid ip", "unknown reason", "protocol not allowed" }; struct s_module *module = get_module(client); memset(&client->grp, 0xff, sizeof(uint64_t)); //client->grp=0xffffffffffffff; if ((intptr_t)account != 0 && (intptr_t)account != -1 && account->disabled) { cs_add_violation(client, account->usr); cs_log("%s %s-client %s%s (%s%sdisabled account)", client->crypted ? t_crypt : t_plain, module->desc, IP_ISSET(client->ip) ? cs_inet_ntoa(client->ip) : "", IP_ISSET(client->ip) ? t_reject : t_reject+1, e_txt ? e_txt : "", e_txt ? " " : ""); return 1; } // check whether client comes in over allowed protocol if ((intptr_t)account != 0 && (intptr_t)account != -1 && (intptr_t)account->allowedprotocols && (((intptr_t)account->allowedprotocols & module->listenertype) != module->listenertype)) { cs_add_violation(client, account->usr); cs_log("%s %s-client %s%s (%s%sprotocol not allowed)", client->crypted ? t_crypt : t_plain, module->desc, IP_ISSET(client->ip) ? cs_inet_ntoa(client->ip) : "", IP_ISSET(client->ip) ? t_reject : t_reject+1, e_txt ? e_txt : "", e_txt ? " " : ""); return 1; } client->account = first_client->account; switch((intptr_t)account) { case 0: { // reject access rc = 1; cs_add_violation(client, NULL); cs_log("%s %s-client %s%s (%s)", client->crypted ? t_crypt : t_plain, module->desc, IP_ISSET(client->ip) ? cs_inet_ntoa(client->ip) : "", IP_ISSET(client->ip) ? t_reject : t_reject+1, e_txt ? e_txt : t_msg[rc]); break; } default: { // grant/check access if (IP_ISSET(client->ip) && account->dyndns) { if (!IP_EQUAL(client->ip, account->dynip)) cs_user_resolve(account); if (!IP_EQUAL(client->ip, account->dynip)) { cs_add_violation(client, account->usr); rc=2; } } client->monlvl = account->monlvl; client->account = account; if (!rc) { client->dup=0; if (client->typ=='c' || client->typ=='m') client->pcrc = crc32(0L, MD5((uchar *)(ESTR(account->pwd)), strlen(ESTR(account->pwd)), md5tmp), MD5_DIGEST_LENGTH); if (client->typ=='c') { client->last_caid = NO_CAID_VALUE; client->last_srvid = NO_SRVID_VALUE; client->expirationdate = account->expirationdate; client->disabled = account->disabled; client->allowedtimeframe[0] = account->allowedtimeframe[0]; client->allowedtimeframe[1] = account->allowedtimeframe[1]; if (account->firstlogin == 0) account->firstlogin = time((time_t*)0); client->failban = account->failban; client->c35_suppresscmd08 = account->c35_suppresscmd08; client->ncd_keepalive = account->ncd_keepalive; client->grp = account->grp; client->aureader_list = account->aureader_list; client->autoau = account->autoau; client->tosleep = (60*account->tosleep); client->c35_sleepsend = account->c35_sleepsend; memcpy(&client->ctab, &account->ctab, sizeof(client->ctab)); if (account->uniq) cs_fake_client(client, account->usr, account->uniq, client->ip); client->ftab = account->ftab; // IDENT filter client->cltab = account->cltab; // CLASS filter client->fchid = account->fchid; // CHID filter client->sidtabs.ok= account->sidtabs.ok; // services client->sidtabs.no= account->sidtabs.no; // services memcpy(&client->ttab, &account->ttab, sizeof(client->ttab)); ac_init_client(client, account); } } } case -1: { // anonymous grant access if (rc) { t_grant = t_reject; } else { if (client->typ == 'm') { snprintf(t_msg[0], sizeof(buf), "lvl=%d", client->monlvl); } else { int32_t rcount = ll_count(client->aureader_list); snprintf(buf, sizeof(buf), "au="); if (!rcount) snprintf(buf+3, sizeof(buf)-3, "off"); else { if (client->autoau) snprintf(buf+3, sizeof(buf)-3, "auto (%d reader)", rcount); else snprintf(buf+3, sizeof(buf)-3, "on (%d reader)", rcount); } } } cs_log("%s %s-client %s%s (%s, %s)", client->crypted ? t_crypt : t_plain, e_txt ? e_txt : module->desc, IP_ISSET(client->ip) ? cs_inet_ntoa(client->ip) : "", IP_ISSET(client->ip) ? t_grant : t_grant + 1, username(client), t_msg[rc]); break; } } return rc; }
int Keeper::collect(const char *path) { #ifdef TEST *logofs << "Keeper: Looking for files in directory '" << path << "'.\n" << logofs_flush; #endif DIR *cacheDir = opendir(path); if (cacheDir != NULL) { File *file; dirent *dirEntry; struct stat fileStat; int baseSize = strlen(path); int fileSize = baseSize + 3 + MD5_LENGTH * 2 + 1; int n = 0; int s = 0; while (((dirEntry = readdir(cacheDir)) != NULL)) { if (s++ % ONCE == 0) usleep(sleep_ * 1000); if (signal_ != 0) break; if (strcmp(dirEntry -> d_name, ".") == 0 || strcmp(dirEntry -> d_name, "..") == 0) { continue; } n++; if (strlen(dirEntry -> d_name) == (MD5_LENGTH * 2 + 2) && (strncmp(dirEntry -> d_name, "I-", 2) == 0 || strncmp(dirEntry -> d_name, "S-", 2) == 0 || strncmp(dirEntry -> d_name, "C-", 2) == 0)) { file = new File(); char *fileName = new char[fileSize]; if (file == NULL || fileName == NULL) { #ifdef WARNING *logofs << "Keeper: WARNING! Can't add file '" << dirEntry -> d_name << "' to repository.\n" << logofs_flush; #endif delete [] fileName; delete file; continue; } strcpy(fileName, path); strcpy(fileName + baseSize, "/"); strcpy(fileName + baseSize + 1, dirEntry -> d_name); file -> name_ = fileName; #ifdef DEBUG *logofs << "Keeper: Adding file '" << file -> name_ << "'.\n" << logofs_flush; #endif if (stat(file -> name_, &fileStat) == -1) { #ifdef WARNING *logofs << "Keeper: WARNING! Can't stat NX file '" << file -> name_ << ". Error is " << EGET() << " '" << ESTR() << "'.\n" << logofs_flush; #endif delete file; continue; } file -> size_ = fileStat.st_size; file -> time_ = fileStat.st_mtime; files_ -> insert(T_files::value_type(file)); total_ += file -> size_; } } closedir(cacheDir); if (n == 0) { time_t now = time(NULL); if (now > 0 && stat(path, &fileStat) == 0) { #ifdef TEST *logofs << "Keeper: Empty NX subdirectory '" << path << "' unused since " << now - fileStat.st_mtime << " S.\n" << logofs_flush; #endif if (now - fileStat.st_mtime > EMPTY_DIR_TIME) { #ifdef TEST *logofs << "Keeper: Removing empty NX subdirectory '" << path << "'.\n" << logofs_flush; #endif rmdir(path); } } } } else { #ifdef WARNING *logofs << "Keeper: WARNING! Can't open NX subdirectory '" << path << ". Error is " << EGET() << " '" << ESTR() << "'.\n" << logofs_flush; #endif cerr << "Warning" << ": Can't open NX subdirectory '" << path << ". Error is " << EGET() << " '" << ESTR() << "'.\n"; } return 1; }
int Keeper::cleanupImages() { #ifdef TEST *logofs << "Keeper: Looking for image directory in '" << root_ << "'.\n" << logofs_flush; #endif char *imagesPath = new char[strlen(root_) + strlen("/images") + 1]; if (imagesPath == NULL) { return -1; } strcpy(imagesPath, root_); strcat(imagesPath, "/images"); // // Check if the cache directory does exist. // struct stat dirStat; if (stat(imagesPath, &dirStat) == -1) { #ifdef WARNING *logofs << "Keeper: WARNING! Can't stat NX images cache directory '" << imagesPath << ". Error is " << EGET() << " '" << ESTR() << "'.\n" << logofs_flush; #endif cerr << "Warning" << ": Can't stat NX images cache directory '" << imagesPath << ". Error is " << EGET() << " '" << ESTR() << "'.\n"; delete [] imagesPath; return -1; } // // Check any of the 16 directories in the // images root path. // char *digitPath = new char[strlen(imagesPath) + 5]; strcpy(digitPath, imagesPath); for (char digit = 0; digit < 16; digit++) { // // Give up if we received a signal or // our parent is gone. // if (signal_ != 0) { #ifdef TEST *logofs << "Keeper: Signal detected. Aborting.\n" << logofs_flush; #endif goto KeeperCleanupImagesAbort; } else if (parent_ != getppid() || parent_ == 1) { #ifdef WARNING *logofs << "Keeper: WARNING! Parent process appears " << "to be dead. Returning.\n" << logofs_flush; #endif goto KeeperCleanupImagesAbort; return 0; } sprintf(digitPath + strlen(imagesPath), "/I-%01X", digit); // // Add to the repository all the files // in the given directory. // collect(digitPath); } delete [] imagesPath; delete [] digitPath; // // Remove the oldest files. // cleanup(images_); // // Empty the repository. // empty(); return 1; KeeperCleanupImagesAbort: delete [] imagesPath; delete [] digitPath; empty(); return 0; }
int Keeper::cleanupCaches() { #ifdef TEST *logofs << "Keeper: Looking for cache directories in '" << root_ << "'.\n" << logofs_flush; #endif DIR *rootDir = opendir(root_); if (rootDir != NULL) { dirent *dirEntry; struct stat fileStat; int baseSize = strlen(root_); int s = 0; while (((dirEntry = readdir(rootDir)) != NULL)) { if (s++ % ONCE == 0) usleep(sleep_ * 1000); if (signal_ != 0) break; if (strcmp(dirEntry -> d_name, "cache") == 0 || strncmp(dirEntry -> d_name, "cache-", 6) == 0) { char *dirName = new char[baseSize + strlen(dirEntry -> d_name) + 2]; if (dirName == NULL) { #ifdef WARNING *logofs << "Keeper: WARNING! Can't check directory entry '" << dirEntry -> d_name << "'.\n" << logofs_flush; #endif delete [] dirName; continue; } strcpy(dirName, root_); strcpy(dirName + baseSize, "/"); strcpy(dirName + baseSize + 1, dirEntry -> d_name); #ifdef TEST *logofs << "Keeper: Checking directory '" << dirName << "'.\n" << logofs_flush; #endif if (stat(dirName, &fileStat) == 0 && S_ISDIR(fileStat.st_mode) != 0) { // // Add to repository all the "C-" and // "S-" files in the given directory. // collect(dirName); } delete [] dirName; } } closedir(rootDir); } else { #ifdef WARNING *logofs << "Keeper: WARNING! Can't open NX root directory '" << root_ << "'. Error is " << EGET() << " '" << ESTR() << "'.\n" << logofs_flush; #endif cerr << "Warning" << ": Can't open NX root directory '" << root_ << "'. Error is " << EGET() << " '" << ESTR() << "'.\n"; } // // Remove older files. // cleanup(caches_); // // Empty the repository. // empty(); return 1; }
int Service::logCheck(const char *file, const char *search) { FILE *fp; char line[DEFAULT_STRING_LENGTH]; int found; if (file == NULL) { #ifdef WARNING logUser("Service::logCheck: WARNING! No file specified."); #endif return 0; } fp = fopen(file, "r"); if (fp == NULL) { #ifdef WARNING logUser("Service::logCheck: WARNING! Cannot open the file: (error %d) %s", EGET(), ESTR()); #endif return 0; } // // TODO: This function could be optimized using // the search stream direction. // found = 0; while (!feof(fp)) { fgets(line, DEFAULT_STRING_LENGTH-1, fp); #ifdef TEST logUser("Service::logCheck: Going to examine line [%s].", line); #endif if (strstr(line, search) != NULL) { found = 1; break; } } fclose(fp); return (found); }
/* convenience wrapper for send with SCM_CREDENTIALS */ static int sendcred(int sock, const void *dat, unsigned int len, int flags) { struct ucred *pcred; union { struct cmsghdr hdr; char dat[CMSG_SPACE(sizeof(struct ucred))]; } cmsg = { .hdr.cmsg_len = CMSG_LEN(sizeof(struct ucred)), .hdr.cmsg_level = SOL_SOCKET, .hdr.cmsg_type = SCM_CREDENTIALS, }; struct iovec iov = { .iov_base = (void *)dat, .iov_len = len, }; struct msghdr msg = { .msg_iov = &iov, .msg_iovlen = 1, .msg_control = &cmsg, .msg_controllen = cmsg.hdr.cmsg_len, }; pcred = (void *)CMSG_DATA(&cmsg.hdr); pcred->pid = getpid(); pcred->uid = getuid(); pcred->gid = getgid(); return sendmsg(sock, &msg, flags); } static int ttytest(void) { int fd; fd = open("/dev/tty", O_RDWR); close(fd); /* /dev/tty can only open when a controlling terminal is opened, * /dev/console is not one of them */ return fd >= 0; } /* main process */ int main(int argc, char *argv[]) { int ret, opt, sock, j, pos; struct sockaddr_un name = { .sun_family = AF_UNIX, .sun_path = "\0rund", }; double repeat = NAN; int maxdelay = 0; time_t t0; int quiet; /* prepare cmd */ static char sbuf[16*1024], rbuf[16*1024]; char *bufp, *str; /* assume quiet operation on non-terminal invocation */ quiet = !ttytest(); /* parse program options */ while ((opt = getopt(argc, argv, optstring)) != -1) switch (opt) { case 'V': fprintf(stderr, "%s: %s\n", NAME, VERSION); return 0; case 'q': quiet = 1; break; case 'r': repeat = optarg ? strtod(optarg, NULL) : 1; if (!(repeat > 0)) mylog(LOG_ERR, "bad rate '%s'", optarg); break; case 's': if (*optarg != '@') mylog(LOG_ERR, "bad socket name '%s'", optarg); strcpy(name.sun_path+1, optarg+1); break; case 'm': maxdelay = ceil(strtod(optarg, NULL)); break; default: fprintf(stderr, "%s: option '%c' unrecognised\n", NAME, opt); case '?': fputs(help_msg, stderr); exit(1); } for (j = optind, bufp = sbuf; j < argc; ++j) { if (!strncmp("USER="******"user '%s' unknown", argv[j]+5); /* add the argument manually * don't forget to add null terminator */ bufp += sprintf(bufp, "USER=#%u", pw->pw_uid)+1; continue; } strcpy(bufp, argv[j]); bufp += strlen(bufp)+1; } if (bufp <= sbuf) mylog(LOG_ERR, "no command specified"); /* install timeout handler using sigalrm */ signal(SIGALRM, sigalrm); /* open client socket */ ret = sock = socket(PF_UNIX, SOCK_DGRAM, 0); if (ret < 0) mylog(LOG_ERR, "socket(unix, ...) failed: %s", ESTR(errno)); /* connect to server */ ret = connect(sock, (void *)&name, sizeof(name)); if (ret < 0) mylog(LOG_ERR, "connect(@%s) failed: %s", name.sun_path+1, ESTR(errno)); str = name.sun_path+1; str += strlen(str); sprintf(str, "-%i", getpid()); ret = bind(sock, (void *)&name, sizeof(name)); if (ret < 0) mylog(LOG_ERR, "bind(@%s) failed: %s", name.sun_path+1, ESTR(errno)); t0 = time(NULL); do { /* schedule timeout */ alarm(1); /* send command */ ret = sendcred(sock, sbuf, bufp - sbuf, 0); if (ret < 0) mylog(LOG_ERR, "send ...: %s", ESTR(errno)); do { ret = recv(sock, rbuf, sizeof(rbuf)-1, 0); if (ret < 0) mylog(LOG_ERR, "recv ...: %s", ESTR(errno)); if (!ret) mylog(LOG_ERR, "empty response"); rbuf[ret] = 0; if (*rbuf != '>') break; for (pos = 1; pos < ret; ) { if (pos > 1) fputc(' ', stdout); fputs(rbuf+pos, stdout); pos += strlen(rbuf+pos)+1; } printf("\n"); alarm(1); } while (1); ret = strtol(rbuf, NULL, 0); if (ret < 0) mylog(LOG_ERR, "command failed: %s", ESTR(-ret)); if (isnan(repeat)) { if (!quiet) printf("%i\n", ret); break; } if (maxdelay && (!ret || (time(NULL) > (t0+maxdelay)))) { if (!quiet) mylog(LOG_INFO, "%s %s after %lu seconds", sbuf, ret ? "aborted" : "finished", time(NULL)-t0); return !!ret; } /* remove timeout */ alarm(0); if (ret) poll(NULL, 0, repeat*1000); } while (ret); return EXIT_SUCCESS; }
int StaticCompressor::compressBuffer(const unsigned char *plainBuffer, const unsigned int plainSize, unsigned char *&compressedBuffer, unsigned int &compressedSize) { #ifdef DEBUG *logofs << "StaticCompressor: Called for buffer at " << (void *) plainBuffer << ".\n" << logofs_flush; #endif compressedSize = plainSize; if (plainSize < (unsigned int) threshold_) { #ifdef TEST *logofs << "StaticCompressor: Leaving buffer unchanged. " << "Plain size is " << plainSize << " with threshold " << (unsigned int) threshold_ << ".\n" << logofs_flush; #endif return 0; } // // Determine the size of the temporary // buffer. // unsigned int newSize = plainSize + (plainSize / 1000) + 12; // // Allocate a new buffer if it grows // beyond 64K. // if (buffer_ == NULL || (bufferSize_ > 65536 && newSize < bufferSize_ / 2) || newSize > bufferSize_) { delete [] buffer_; buffer_ = new unsigned char[newSize]; if (buffer_ == NULL) { #ifdef PANIC *logofs << "StaticCompressor: PANIC! Can't allocate compression " << "buffer of " << newSize << " bytes. Error is " << EGET() << " ' " << ESTR() << "'.\n" << logofs_flush; #endif cerr << "Warning" << ": Can't allocate compression buffer of " << newSize << " bytes. Error is " << EGET() << " '" << ESTR() << "'.\n"; bufferSize_ = 0; return 0; } bufferSize_ = newSize; } unsigned int resultingSize = newSize; int result = ZCompress(&compressionStream_, buffer_, &resultingSize, plainBuffer, plainSize); if (result == Z_OK) { if (resultingSize > newSize) { #ifdef PANIC *logofs << "StaticCompressor: PANIC! Overflow in compression " << "buffer size. " << "Expected size was " << newSize << " while it is " << resultingSize << ".\n" << logofs_flush; #endif cerr << "Error" << ": Overflow in compress buffer size. " << "Expected size was " << newSize << " while it is " << resultingSize << ".\n"; return -1; } else if (resultingSize >= plainSize) { #ifdef TEST *logofs << "StaticCompressor: Leaving buffer unchanged. " << "Plain size is " << plainSize << " compressed " << "size is " << resultingSize << ".\n" << logofs_flush; #endif return 0; } compressedBuffer = buffer_; compressedSize = resultingSize; #ifdef TEST *logofs << "StaticCompressor: Compressed buffer from " << plainSize << " to " << resultingSize << " bytes.\n" << logofs_flush; #endif return 1; } #ifdef PANIC *logofs << "StaticCompressor: PANIC! Failed compression of buffer. " << "Error is '" << zError(result) << "'.\n" << logofs_flush; #endif cerr << "Error" << ": Failed compression of buffer. " << "Error is '" << zError(result) << "'.\n"; return -1; }
int ServerProxy::handleNewXConnectionFromProxy(int channelId) { // // Connect to the real X server. // int retryConnect = control -> OptionServerRetryConnect; int xServerFd; for (;;) { xServerFd = socket(xServerAddrFamily_, SOCK_STREAM, PF_UNSPEC); if (xServerFd < 0) { #ifdef PANIC *logofs << "ServerProxy: PANIC! Call to socket failed. " << "Error is " << EGET() << " '" << ESTR() << "'.\n" << logofs_flush; #endif cerr << "Error" << ": Call to socket failed. " << "Error is " << EGET() << " '" << ESTR() << "'.\n"; return -1; } #ifdef TEST *logofs << "ServerProxy: Trying to connect to X server '" << xServerDisplay_ << "'.\n" << logofs_flush; #endif int result = connect(xServerFd, xServerAddr_, xServerAddrLength_); getNewTimestamp(); if (result < 0) { #ifdef WARNING *logofs << "ServerProxy: WARNING! Connection to '" << xServerDisplay_ << "' failed with error '" << ESTR() << "'. Retrying.\n" << logofs_flush; #endif close(xServerFd); if (--retryConnect == 0) { #ifdef PANIC *logofs << "ServerProxy: PANIC! Connection to '" << xServerDisplay_ << "' for channel ID#" << channelId << " failed. Error is " << EGET() << " '" << ESTR() << "'.\n" << logofs_flush; #endif cerr << "Error" << ": Connection to '" << xServerDisplay_ << "' failed. Error is " << EGET() << " '" << ESTR() << "'.\n"; close(xServerFd); return -1; } if (activeChannels_.getSize() == 0) { sleep(2); } else { sleep(1); } } else { break; } } assignChannelMap(channelId, xServerFd); #ifdef TEST *logofs << "ServerProxy: X server descriptor FD#" << xServerFd << " mapped to channel ID#" << channelId << ".\n" << logofs_flush; #endif // // Turn queuing off for path proxy-to-X-server. // if (control -> OptionServerNoDelay == 1) { SetNoDelay(xServerFd, control -> OptionServerNoDelay); } // // If requested, set the size of the TCP send // and receive buffers. // if (control -> OptionServerSendBuffer != -1) { SetSendBuffer(xServerFd, control -> OptionServerSendBuffer); } if (control -> OptionServerReceiveBuffer != -1) { SetReceiveBuffer(xServerFd, control -> OptionServerReceiveBuffer); } if (allocateTransport(xServerFd, channelId) < 0) { return -1; } // // Starting from protocol level 3 client and server // caches are created in proxy and shared between all // channels. If remote proxy has older protocol level // pointers are NULL and channels must create their // own instances. // channels_[channelId] = new ServerChannel(transports_[channelId], compressor_); if (channels_[channelId] == NULL) { deallocateTransport(channelId); return -1; } increaseChannels(channelId); // // Propagate channel stores and caches to the new // channel. // channels_[channelId] -> setOpcodes(opcodeStore_); channels_[channelId] -> setStores(clientStore_, serverStore_); channels_[channelId] -> setCaches(clientCache_, serverCache_); int port = atoi(fontServerPort_); if (port > 0) { channels_[channelId] -> setPorts(port); } // // Let channel configure itself according // to control parameters. // channels_[channelId] -> handleConfiguration(); // // Check if we have successfully loaded the // selected cache and, if not, remove it // from disk. // handleCheckLoad(); return 1; }
FILE *Popen(char * const parameters[], const char *type) { FILE *iop; struct pid *cur; int pdes[2], pid; if (parameters == NULL || type == NULL) { return NULL; } if ((*type != 'r' && *type != 'w') || type[1]) { return NULL; } if ((cur = (struct pid *) malloc(sizeof(struct pid))) == NULL) { return NULL; } if (pipe(pdes) < 0) { free(cur); return NULL; } // // Block all signals until command is exited. // We need to gather information about the // child in Pclose(). // DisableSignals(); switch (pid = Fork()) { case -1: { // // Error. // #ifdef PANIC *logofs << "Popen: PANIC! Function fork failed. " << "Error is " << EGET() << " '" << ESTR() << "'.\n" << logofs_flush; #endif cerr << "Error" << ": Function fork failed. " << "Error is " << EGET() << " '" << ESTR() << "'.\n"; close(pdes[0]); close(pdes[1]); free(cur); return NULL; } case 0: { // // Child. // setgid(getgid()); setuid(getuid()); if (*type == 'r') { if (pdes[1] != 1) { // // Set up stdout. // dup2(pdes[1], 1); close(pdes[1]); } close(pdes[0]); } else { if (pdes[0] != 0) { // // Set up stdin. // dup2(pdes[0], 0); close(pdes[0]); } close(pdes[1]); } execvp(parameters[0], parameters + 1); exit(127); } } // // Parent. Save data about the child. // RegisterChild(pid); if (*type == 'r') { iop = fdopen(pdes[0], type); close(pdes[1]); } else { iop = fdopen(pdes[1], type); close(pdes[0]); } cur -> fp = iop; cur -> self = pid; cur -> next = pidlist; pidlist = cur; #ifdef TEST *logofs << "Popen: Executing "; for (int i = 0; i < 256 && parameters[i] != NULL; i++) { *logofs << "[" << parameters[i] << "]"; } *logofs << " with descriptor " << fileno(iop) << ".\n" << logofs_flush; #endif return iop; }