/******************************************************************************* * Find a FastCGI server with a matching fs_path, and if fcgi_wrapper is * enabled with matching uid and gid. */ fcgi_server * fcgi_util_fs_get_by_id(const char *ePath, uid_t uid, gid_t gid) { char path[FCGI_MAXPATH]; fcgi_server *s; /* @@@ This should now be done in the loop below */ ap_cpystrn(path, ePath, FCGI_MAXPATH); ap_no2slash(path); for (s = fcgi_servers; s != NULL; s = s->next) { int i; const char *fs_path = s->fs_path; for (i = 0; fs_path[i] && path[i]; ++i) { if (fs_path[i] != path[i]) { break; } } if (fs_path[i]) { continue; } if (path[i] == '\0' || path[i] == '/') { if (fcgi_wrapper == NULL || (uid == s->uid && gid == s->gid)) return s; } } return NULL; }
void *ssl_ds_table_push(ssl_ds_table *t, char *key) { char *k; void *d; k = (char *)ap_push_array(t->aKey); d = (void *)ap_push_array(t->aData); ap_cpystrn(k, key, t->aKey->elt_size); return d; }
static const char *set_default_order(cmd_parms *cmd, void *m, char *direction, char *key) { char temp[4]; autoindex_config_rec *d_cfg = (autoindex_config_rec *) m; ap_cpystrn(temp, "k=d", sizeof(temp)); if (!strcasecmp(direction, "Ascending")) { temp[2] = D_ASCENDING; } else if (!strcasecmp(direction, "Descending")) { temp[2] = D_DESCENDING; } else { return "First keyword must be 'Ascending' or 'Descending'"; } if (!strcasecmp(key, "Name")) { temp[0] = K_NAME; } else if (!strcasecmp(key, "Date")) { temp[0] = K_LAST_MOD; } else if (!strcasecmp(key, "Size")) { temp[0] = K_SIZE; } else if (!strcasecmp(key, "Description")) { temp[0] = K_DESC; } else { return "Second keyword must be 'Name', 'Date', 'Size', or " "'Description'"; } if (d_cfg->default_order == NULL) { d_cfg->default_order = ap_palloc(cmd->pool, 4); d_cfg->default_order[3] = '\0'; } ap_cpystrn(d_cfg->default_order, temp, sizeof(temp)); return NULL; }
API_EXPORT(int) ap_getpass(const char *prompt, char *pwbuf, size_t bufsiz) { char *pw_got; int result = 0; pw_got = getpass(prompt); if (strlen(pw_got) > (bufsiz - 1)) { result = ERR_OVERFLOW; } ap_cpystrn(pwbuf, pw_got, bufsiz); return result; }
static BOOL SendResponseHeaderEx(isapi_cid *cid, const char *stat, const char *head, DWORD statlen, DWORD headlen) { int termarg; char *termch; if (!stat || statlen == 0 || !*stat) { stat = "Status: 200 OK"; } else { char *newstat; newstat = ap_palloc(cid->r->pool, statlen + 9); strcpy(newstat, "Status: "); ap_cpystrn(newstat + 8, stat, statlen + 1); stat = newstat; } if (!head || headlen == 0 || !*head) { head = "\r\n"; } else { if (head[headlen]) { /* Whoops... not NULL terminated */ head = ap_pstrndup(cid->r->pool, head, headlen); } } /* Parse them out, or die trying */ cid->status = ap_scan_script_header_err_strs(cid->r, NULL, &termch, &termarg, stat, head, NULL); cid->ecb->dwHttpStatusCode = cid->r->status; /* All the headers should be set now */ ap_send_http_header(cid->r); /* Any data left should now be sent directly, * it may be raw if headlen was provided. */ if (termch && (termarg == 1)) { if (headlen == -1 && *termch) ap_rputs(termch, cid->r); else if (headlen > (size_t) (termch - head)) ap_rwrite(termch, headlen - (termch - head), cid->r); } if (cid->status == HTTP_INTERNAL_SERVER_ERROR) return FALSE; return TRUE; }
/* * Make a password record from the given information. A zero return * indicates success; failure means that the output buffer contains an * error message instead. */ static int mkrecord(char *user, char *record, size_t rlen, char *passwd, int alg) { char *pw; char cpw[120]; char pwin[MAX_STRING_LEN]; char pwv[MAX_STRING_LEN]; char salt[9]; if (passwd != NULL) { pw = passwd; } switch (alg) { case ALG_CRYPT: default: (void) srand((int) time((time_t *) NULL)); ap_to64(&salt[0], rand(), 8); salt[8] = '\0'; ap_cpystrn(cpw, (char *)crypt(pw, salt), sizeof(cpw) - 1); break; } memset(pw, '\0', strlen(pw)); /* * Check to see if the buffer is large enough to hold the username, * hash, and delimiters. */ if ((strlen(user) + 1 + strlen(cpw)) > (rlen - 1)) { ap_cpystrn(record, "resultant record too long", (rlen - 1)); return ERR_OVERFLOW; } strcpy(record, user); strcat(record, ":"); strcat(record, cpw); return 0; }
/* It stores the account name for later use */ const char *os_set_account(pool *p, const char *account) { char account_temp[ACCT_LEN+1]; ap_cpystrn(account_temp, account, sizeof account_temp); /* Make account all upper case */ ap_str_toupper(account_temp); /* Pad to length 8 */ ap_pad(account_temp, sizeof account_temp, ' '); bs2000_account = ap_pstrdup(p, account_temp); return NULL; }
static void ssl_io_data_dump(server_rec *srvr, const char *s, long len) { char buf[256]; char tmp[64]; int i, j, rows, trunc; unsigned char ch; trunc = 0; for(; (len > 0) && ((s[len-1] == ' ') || (s[len-1] == '\0')); len--) trunc++; rows = (len / DUMP_WIDTH); if ((rows * DUMP_WIDTH) < len) rows++; ssl_log(srvr, SSL_LOG_DEBUG|SSL_NO_TIMESTAMP|SSL_NO_LEVELID, "+-------------------------------------------------------------------------+"); for (i = 0 ; i< rows; i++) { ap_snprintf(tmp, sizeof(tmp), "| %04x: ", i * DUMP_WIDTH); ap_cpystrn(buf, tmp, sizeof(buf)); for (j = 0; j < DUMP_WIDTH; j++) { if (((i * DUMP_WIDTH) + j) >= len) ap_cpystrn(buf+strlen(buf), " ", sizeof(buf)-strlen(buf)); else { ch = ((unsigned char)*((char *)(s) + i * DUMP_WIDTH + j)) & 0xff; ap_snprintf(tmp, sizeof(tmp), "%02x%c", ch , j==7 ? '-' : ' '); ap_cpystrn(buf+strlen(buf), tmp, sizeof(buf)-strlen(buf)); } } ap_cpystrn(buf+strlen(buf), " ", sizeof(buf)-strlen(buf)); for (j = 0; j < DUMP_WIDTH; j++) { if (((i * DUMP_WIDTH) + j) >= len) ap_cpystrn(buf+strlen(buf), " ", sizeof(buf)-strlen(buf)); else { ch = ((unsigned char)*((char *)(s) + i * DUMP_WIDTH + j)) & 0xff; ap_snprintf(tmp, sizeof(tmp), "%c", ((ch >= ' ') && (ch <= '~')) ? ch : '.'); ap_cpystrn(buf+strlen(buf), tmp, sizeof(buf)-strlen(buf)); } } ap_cpystrn(buf+strlen(buf), " |", sizeof(buf)-strlen(buf)); ssl_log(srvr, SSL_LOG_DEBUG|SSL_NO_TIMESTAMP|SSL_NO_LEVELID, "%s", buf); } if (trunc > 0) ssl_log(srvr, SSL_LOG_DEBUG|SSL_NO_TIMESTAMP|SSL_NO_LEVELID, "| %04lx - <SPACES/NULS>", len + trunc); ssl_log(srvr, SSL_LOG_DEBUG|SSL_NO_TIMESTAMP|SSL_NO_LEVELID, "+-------------------------------------------------------------------------+"); return; }
/* retrieve subject CommonName of certificate */ BOOL SSL_X509_getCN(pool *p, X509 *xs, char **cppCN) { X509_NAME *xsn; X509_NAME_ENTRY *xsne; int i, nid; xsn = X509_get_subject_name(xs); for (i = 0; i < sk_X509_NAME_ENTRY_num(xsn->entries); i++) { xsne = sk_X509_NAME_ENTRY_value(xsn->entries, i); nid = OBJ_obj2nid(xsne->object); if (nid == NID_commonName) { *cppCN = ap_palloc(p, xsne->value->length+1); ap_cpystrn(*cppCN, (char *)xsne->value->data, xsne->value->length+1); (*cppCN)[xsne->value->length] = NUL; #ifdef CHARSET_EBCDIC ascii2ebcdic(*cppCN, *cppCN, strlen(*cppCN)); #endif return TRUE; } } return FALSE; }
/******************************************************************************* * Find a FastCGI server with a matching fs_path, and if fcgi_wrapper is * enabled with matching user and group. */ fcgi_server * fcgi_util_fs_get(const char *ePath, const char *user, const char *group) { char path[FCGI_MAXPATH]; fcgi_server *s; ap_cpystrn(path, ePath, FCGI_MAXPATH); ap_no2slash(path); for (s = fcgi_servers; s != NULL; s = s->next) { if (strcmp(s->fs_path, path) == 0) { if (fcgi_wrapper == NULL) return s; if (strcmp(user, s->user) == 0 && (user[0] == '~' || strcmp(group, s->group) == 0)) { return s; } } } return NULL; }
/* BS2000 requires a "special" version of fork() before a setuid()/_rini() call */ pid_t os_fork(const char *user) { pid_t pid; char username[USER_LEN+1]; switch (os_forktype()) { case bs2_FORK: case bs2_FORK_RINI: pid = fork(); break; case bs2_RFORK_RINI: pid = _rfork(); break; case bs2_UFORK: ap_cpystrn(username, user, sizeof username); /* Make user name all upper case - for some versions of ufork() */ ap_str_toupper(username); pid = ufork(username); if (pid == -1 && errno == EPERM) { ap_log_error(APLOG_MARK, APLOG_EMERG, NULL, "ufork: Possible mis-configuration " "for user %s - Aborting.", user); exit(1); } break; default: pid = 0; break; } return pid; }
char *get_tag(int tagbuf_len) { char *tag_val, c, term; t = 0; --tagbuf_len; do { GET_CHAR(c, NULL); } while (ap_isspace(c)); if (c == '-') { GET_CHAR(c, NULL); if (c == '-') { do { GET_CHAR(c, NULL); } while (ap_isspace(c)); if (c == '>') { ap_cpystrn(tag, "done", tagbuf_len); return tag; } } return NULL; } while (1) { if (t == tagbuf_len) { tag[t] = EOS; return NULL; } if (c == '=' || ap_isspace(c)) { break; } tag[t] = ap_tolower(c); t++; GET_CHAR(c, NULL); } tag[t] = EOS; t++; tag_val = tag + t; while (ap_isspace(c)) { GET_CHAR(c, NULL); } if (c != '=') { return NULL; } do { GET_CHAR(c, NULL); } while (ap_isspace(c)); if (c != '"' && c != '\'') { return NULL; } term = c; while (1) { GET_CHAR(c, NULL); if (t == tagbuf_len) { /* Suppose t == tagbuf_len - 1 */ tag[t] = EOS; return NULL; } if (c == '\\') { GET_CHAR(c, NULL); if (c != term) { /* OK */ tag[t] = '\\'; t++; if (t == tagbuf_len) { /* OK */ __TESTCLAIM_1: tag[t] = EOS; return NULL; } } } else if (c == term) { break; } /* OK */ tag[t] = c; t++; /* Now t == tagbuf_len + 1 * So the bounds check (t == tagbuf_len) will fail */ } /* OK */ tag[t] = EOS; return tag; }
/* This routine complements the setuid() call: it causes the BS2000 job * environment to be switched to the target user's user id. * That is important if CGI scripts try to execute native BS2000 commands. */ int os_init_job_environment(server_rec *server, const char *user_name, int one_process) { _rini_struct inittask; char username[USER_LEN+1]; bs2_ForkType type = os_forktype(); /* We can be sure that no change to uid==0 is possible because of * the checks in http_core.c:set_user() */ /* The _rini() function works only after a prior _rfork(). * In the case of one_process, it would fail. */ if (one_process) { type = forktype = bs2_noFORK; ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, server, "The debug mode of Apache should only " "be started by an unprivileged user!"); return 0; } /* If no _rini() is required, then return quickly. */ if (type != bs2_RFORK_RINI && type != bs2_FORK_RINI) return 0; /* An Account is required for _rini() */ if (bs2000_account == NULL) { ap_log_error(APLOG_MARK, APLOG_ALERT|APLOG_NOERRNO, server, "No BS2000Account configured - cannot switch to User %s", user_name); exit(APEXIT_CHILDFATAL); } ap_cpystrn(username, user_name, sizeof username); /* Make user name all upper case */ ap_str_toupper(username); /* Pad to length 8 */ ap_pad(username, sizeof username, ' '); inittask.username = username; inittask.account = bs2000_account; inittask.processor_name = " "; /* Switch to the new logon user (setuid() and setgid() are done later) */ /* Only the super user can switch identities. */ if (_rini(&inittask) != 0) { ap_log_error(APLOG_MARK, APLOG_ALERT, server, "_rini: BS2000 auth failed for user \"%s\" acct \"%s\"", inittask.username, inittask.account); exit(APEXIT_CHILDFATAL); } return 0; }
int main(int argc, char *argv[]) { FILE *tfp, *f; char user[MAX_STRING_LEN]; char realm[MAX_STRING_LEN]; char line[MAX_STRING_LEN]; char l[MAX_STRING_LEN]; char w[MAX_STRING_LEN]; char x[MAX_STRING_LEN]; char command[MAX_STRING_LEN]; int found; tn = NULL; signal(SIGINT, (void (*)(int)) interrupted); if (argc == 5) { if (strcmp(argv[1], "-c")) usage(); #ifdef NETWARE UnAugmentAsterisk(TRUE); SetCurrentNameSpace(NW_NS_LONG); SetTargetNameSpace(NW_NS_LONG); #endif if (!(tfp = fopen(argv[2], "w"))) { fprintf(stderr, "Could not open passwd file %s for writing.\n", argv[2]); perror("fopen"); exit(1); } printf("Adding password for %s in realm %s.\n", argv[4], argv[3]); add_password(argv[4], argv[3], tfp); fclose(tfp); exit(0); } else if (argc != 4) usage(); tn = tmpnam(NULL); if (!(tfp = fopen(tn, "w"))) { fprintf(stderr, "Could not open temp file.\n"); exit(1); } if (!(f = fopen(argv[1], "r"))) { fprintf(stderr, "Could not open passwd file %s for reading.\n", argv[1]); fprintf(stderr, "Use -c option to create new one.\n"); exit(1); } ap_cpystrn(user, argv[3], sizeof(user)); ap_cpystrn(realm, argv[2], sizeof(realm)); found = 0; while (!(getline(line, MAX_STRING_LEN, f))) { if (found || (line[0] == '#') || (!line[0])) { putline(tfp, line); continue; } strcpy(l, line); getword(w, l, ':'); getword(x, l, ':'); if (strcmp(user, w) || strcmp(realm, x)) { putline(tfp, line); continue; } else { printf("Changing password for user %s in realm %s\n", user, realm); add_password(user, realm, tfp); found = 1; } } if (!found) { printf("Adding user %s in realm %s\n", user, realm); add_password(user, realm, tfp); } fclose(f); fclose(tfp); #ifndef NETWARE #if defined(OS2) || defined(WIN32) sprintf(command, "copy \"%s\" \"%s\"", tn, argv[1]); #else sprintf(command, "cp %s %s", tn, argv[1]); #endif system(command); #else if (!(tfp = fopen(tn, "r"))) { fprintf(stderr, "Could not open temp file.\n"); exit(1); } if (!(f = fopen(argv[1], "w"))) { fprintf(stderr, "Could not open %s.\n", argv[1]); exit(1); } copy_file(f, tfp); #endif unlink(tn); return 0; }
char *get_tag(char *tag , int tagbuf_len ) { char *tag_val ; char c ; char term ; int t ; int tmp ; int tmp___0 ; int tmp___1 ; int tmp___2 ; int tmp___3 ; int tmp___4 ; int tmp___5 ; int tmp___6 ; int tmp___7 ; int tmp___8 ; int tmp___9 ; int tmp___10 ; int tmp___11 ; int tmp___12 ; int __cil_tmp21 ; int __cil_tmp22 ; int __cil_tmp23 ; void *__cil_tmp24 ; char *__cil_tmp25 ; void *__cil_tmp26 ; int __cil_tmp27 ; char *__cil_tmp28 ; char *__cil_tmp29 ; int __cil_tmp30 ; void *__cil_tmp31 ; int __cil_tmp32 ; int __cil_tmp33 ; void *__cil_tmp34 ; char *__cil_tmp35 ; void *__cil_tmp36 ; int __cil_tmp37 ; int __cil_tmp38 ; int __cil_tmp39 ; int __cil_tmp40 ; char *__cil_tmp41 ; char *__cil_tmp42 ; void *__cil_tmp43 ; int __cil_tmp44 ; int __cil_tmp45 ; int __cil_tmp46 ; char *__cil_tmp47 ; char *__cil_tmp48 ; { #line 9 t = 0; #line 11 tagbuf_len = tagbuf_len - 1; { #line 13 while (1) { while_0_continue: /* CIL Label */ ; { #line 14 tmp = __VERIFIER_nondet_char(); #line 14 c = (char )tmp; #line 13 tmp___0 = ap_isspace(c); } #line 13 if (tmp___0) { } else { goto while_0_break; } } while_0_break: /* CIL Label */ ; } { #line 17 __cil_tmp21 = (int )c; #line 17 if (__cil_tmp21 == 45) { { #line 18 tmp___1 = __VERIFIER_nondet_char(); #line 18 c = (char )tmp___1; } { #line 19 __cil_tmp22 = (int )c; #line 19 if (__cil_tmp22 == 45) { { #line 20 while (1) { while_1_continue: /* CIL Label */ ; { #line 21 tmp___2 = __VERIFIER_nondet_char(); #line 21 c = (char )tmp___2; #line 20 tmp___3 = ap_isspace(c); } #line 20 if (tmp___3) { } else { goto while_1_break; } } while_1_break: /* CIL Label */ ; } { #line 23 __cil_tmp23 = (int )c; #line 23 if (__cil_tmp23 == 62) { { #line 24 ap_cpystrn(tag, "done", tagbuf_len); } #line 25 return (tag); } else { } } } else { } } { #line 28 __cil_tmp24 = (void *)0; #line 28 return ((char *)__cil_tmp24); } } else { } } { #line 31 while (1) { while_2_continue: /* CIL Label */ ; #line 32 if (t == tagbuf_len) { #line 33 __cil_tmp25 = tag + t; #line 33 *__cil_tmp25 = (char)0; { #line 34 __cil_tmp26 = (void *)0; #line 34 return ((char *)__cil_tmp26); } } else { } { #line 36 __cil_tmp27 = (int )c; #line 36 if (__cil_tmp27 == 61) { goto while_2_break; } else { { #line 36 tmp___4 = ap_isspace(c); } #line 36 if (tmp___4) { goto while_2_break; } else { } } } { #line 39 tmp___5 = ap_tolower(c); #line 39 __cil_tmp28 = tag + t; #line 39 *__cil_tmp28 = (char )tmp___5; #line 40 t = t + 1; #line 41 tmp___6 = __VERIFIER_nondet_char(); #line 41 c = (char )tmp___6; } } while_2_break: /* CIL Label */ ; } #line 44 __cil_tmp29 = tag + t; #line 44 *__cil_tmp29 = (char)0; #line 45 t = t + 1; #line 46 tag_val = tag + t; { #line 48 while (1) { while_3_continue: /* CIL Label */ ; { #line 48 tmp___8 = ap_isspace(c); } #line 48 if (tmp___8) { } else { goto while_3_break; } { #line 49 tmp___7 = __VERIFIER_nondet_char(); #line 49 c = (char )tmp___7; } } while_3_break: /* CIL Label */ ; } { #line 51 __cil_tmp30 = (int )c; #line 51 if (__cil_tmp30 != 61) { { #line 52 __cil_tmp31 = (void *)0; #line 52 return ((char *)__cil_tmp31); } } else { } } { #line 55 while (1) { while_4_continue: /* CIL Label */ ; { #line 56 tmp___9 = __VERIFIER_nondet_char(); #line 56 c = (char )tmp___9; #line 55 tmp___10 = ap_isspace(c); } #line 55 if (tmp___10) { } else { goto while_4_break; } } while_4_break: /* CIL Label */ ; } { #line 59 __cil_tmp32 = (int )c; #line 59 if (__cil_tmp32 != 34) { { #line 59 __cil_tmp33 = (int )c; #line 59 if (__cil_tmp33 != 39) { { #line 60 __cil_tmp34 = (void *)0; #line 60 return ((char *)__cil_tmp34); } } else { } } } else { } } #line 62 term = c; { #line 63 while (1) { while_5_continue: /* CIL Label */ ; { #line 64 tmp___11 = __VERIFIER_nondet_char(); #line 64 c = (char )tmp___11; } #line 65 if (t == tagbuf_len) { #line 66 __cil_tmp35 = tag + t; #line 66 *__cil_tmp35 = (char)0; { #line 67 __cil_tmp36 = (void *)0; #line 67 return ((char *)__cil_tmp36); } } else { } { #line 70 __cil_tmp37 = (int )c; #line 70 if (__cil_tmp37 == 92) { { #line 71 tmp___12 = __VERIFIER_nondet_char(); #line 71 c = (char )tmp___12; } { #line 72 __cil_tmp38 = (int )term; #line 72 __cil_tmp39 = (int )c; #line 72 if (__cil_tmp39 != __cil_tmp38) { { #line 74 __cil_tmp40 = t + 1; #line 74 if (__cil_tmp40 < tagbuf_len) { } else { { #line 74 __assert_fail("t + 1 < tagbuf_len", "../versisec/apache/progs/apacheCVE-2004-0940get_tag_iter1_prefixLong_arr_ok.c", 74U, "get_tag"); } } } #line 77 __cil_tmp41 = tag + t; #line 77 *__cil_tmp41 = (char )'\\'; #line 78 t = t + 1; #line 79 if (t == tagbuf_len) { #line 81 __cil_tmp42 = tag + t; #line 81 *__cil_tmp42 = (char)0; { #line 82 __cil_tmp43 = (void *)0; #line 82 return ((char *)__cil_tmp43); } } else { } } else { } } } else { { #line 86 __cil_tmp44 = (int )term; #line 86 __cil_tmp45 = (int )c; #line 86 if (__cil_tmp45 == __cil_tmp44) { goto while_5_break; } else { } } } } { #line 91 __cil_tmp46 = t + 2; #line 91 if (__cil_tmp46 < tagbuf_len) { } else { { #line 91 __assert_fail("t + 2 < tagbuf_len", "../versisec/apache/progs/apacheCVE-2004-0940get_tag_iter1_prefixLong_arr_ok.c", 91U, "get_tag"); } } } #line 94 __cil_tmp47 = tag + t; #line 94 *__cil_tmp47 = c; #line 95 t = t + 1; } while_5_break: /* CIL Label */ ; } #line 99 __cil_tmp48 = tag + t; #line 99 *__cil_tmp48 = (char)0; #line 101 return (tag); } }
/* * ic_server_setup() * ----------------- * Do the actual primary/backup server setup on behalf of the * ic_server_cmd() and ic_serverbackup_cmd() functions. */ static const char *ic_server_setup(cmd_parms *parms,void *mconfig,int server,const char *arg) { static char errmsg[100]; ic_conf_rec *conf_rec = (ic_conf_rec *)mconfig; ic_socket_rec *sock_rec = conf_rec->server[server]; sock_rec->address = ap_pstrdup(parms->pool,arg); if (sock_rec->address == NULL) return "not enough memory for the socket address"; /* * verify type of the argument, which will indicate * whether we should be using a UNIX or Inet socket * to connect to the Interchange server */ if (*arg == '/'){ /* * this is to be a UNIX socket */ struct sockaddr_un *unix_sock; unix_sock = (struct sockaddr_un *)ap_pcalloc(parms->pool,sizeof(struct sockaddr_un)); if (unix_sock == NULL){ sprintf(errmsg,"not enough memory for %s UNIX socket structure",server ? "primary" : "backup"); return errmsg; } unix_sock->sun_family = AF_LOCAL; ap_cpystrn(unix_sock->sun_path,sock_rec->address,sizeof(unix_sock->sun_path)); sock_rec->sockaddr = (struct sockaddr *)unix_sock; sock_rec->size = SUN_LEN(unix_sock); sock_rec->family = PF_LOCAL; }else{ /* * this is to be an INET socket * * the argument is an IP address or hostname followed by * an optional port specification */ struct sockaddr_in *inet_sock; char **hostaddress; char *hostname; inet_sock = (struct sockaddr_in *)ap_pcalloc(parms->pool,sizeof(struct sockaddr_in)); if (inet_sock == NULL){ sprintf(errmsg,"not enough memory for %s INET socket structure",server ? "primary" : "backup"); return errmsg; } inet_sock->sin_family = AF_INET; hostaddress = &(sock_rec->address); hostname = ap_getword_nc(parms->temp_pool,hostaddress,':'); if (!inet_aton(hostname,&inet_sock->sin_addr)){ /* * address must point to a hostname */ struct hostent *host = ap_pgethostbyname(parms->temp_pool,hostname); if (!host) return "invalid hostname specification"; memcpy(&inet_sock->sin_addr,host->h_addr,sizeof(inet_sock->sin_addr)); } /* * check if a port number has been specified */ if (**hostaddress){ int port = atoi(*hostaddress); if (port <= 100 || port > 65535) return "invalid port specification"; inet_sock->sin_port = htons(port); }else{ inet_sock->sin_port = htons(IC_DEFAULT_PORT); } sock_rec->sockaddr = (struct sockaddr *)inet_sock; sock_rec->family = PF_INET; sock_rec->size = sizeof(struct sockaddr_in); } return NULL; }
/* XXX: Is there is still an O(n^2) attack possible here? Please detail. */ BOOL WINAPI ServerSupportFunction (HCONN hConn, DWORD dwHSERequest, LPVOID lpvBuffer, LPDWORD lpdwSize, LPDWORD lpdwDataType) { isapi_cid *cid = (isapi_cid *)hConn; request_rec *r = cid->r; request_rec *subreq; switch (dwHSERequest) { case 1: /* HSE_REQ_SEND_URL_REDIRECT_RESP */ /* Set the status to be returned when the HttpExtensionProc() * is done. * WARNING: Microsoft now advertises HSE_REQ_SEND_URL_REDIRECT_RESP * and HSE_REQ_SEND_URL as equivalant per the Jan 2000 SDK. * They most definately are not, even in their own samples. */ ap_table_set(r->headers_out, "Location", lpvBuffer); cid->status = cid->r->status = cid->ecb->dwHttpStatusCode = HTTP_MOVED_TEMPORARILY; return TRUE; case 2: /* HSE_REQ_SEND_URL */ /* Soak up remaining input (there should be none) */ if (r->remaining > 0) { char argsbuffer[HUGE_STRING_LEN]; while (ap_get_client_block(r, argsbuffer, HUGE_STRING_LEN) > 0); } /* Reset the method to GET */ r->method = ap_pstrdup(r->pool, "GET"); r->method_number = M_GET; /* Don't let anyone think there's still data */ ap_table_unset(r->headers_in, "Content-Length"); /* AV fault per PR3598 - redirected path is lost! */ (char*)lpvBuffer = ap_pstrdup(r->pool, (char*)lpvBuffer); ap_internal_redirect((char*)lpvBuffer, r); return TRUE; case 3: /* HSE_REQ_SEND_RESPONSE_HEADER */ { /* Parse them out, or die trying */ DWORD statlen = 0, headlen = 0; if (lpvBuffer) statlen = strlen((char*) lpvBuffer); if (lpdwDataType) headlen = strlen((char*) lpdwDataType); return SendResponseHeaderEx(cid, (char*) lpvBuffer, (char*) lpdwDataType, statlen, headlen); } case 4: /* HSE_REQ_DONE_WITH_SESSION */ /* Do nothing... since we don't support async I/O, they'll * return from HttpExtensionProc soon */ return TRUE; case 1001: /* HSE_REQ_MAP_URL_TO_PATH */ { /* Map a URL to a filename */ char *file = (char *)lpvBuffer; DWORD len; subreq = ap_sub_req_lookup_uri(ap_pstrndup(r->pool, file, *lpdwSize), r); len = ap_cpystrn(file, subreq->filename, *lpdwSize) - file; /* IIS puts a trailing slash on directories, Apache doesn't */ if (S_ISDIR (subreq->finfo.st_mode)) { if (len < *lpdwSize - 1) { file[len++] = '\\'; file[len] = '\0'; } } *lpdwSize = len; return TRUE; } case 1002: /* HSE_REQ_GET_SSPI_INFO */ if (LogNotSupported) ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, r, "ISAPI ServerSupportFunction HSE_REQ_GET_SSPI_INFO " "is not supported: %s", r->filename); SetLastError(ERROR_INVALID_PARAMETER); return FALSE; case 1003: /* HSE_APPEND_LOG_PARAMETER */ /* Log lpvBuffer, of lpdwSize bytes, in the URI Query (cs-uri-query) field * This code will do for now... */ ap_table_set(r->notes, "isapi-parameter", (char*) lpvBuffer); if (AppendLogToQuery) { if (r->args) r->args = ap_pstrcat(r->pool, r->args, (char*) lpvBuffer, NULL); else r->args = ap_pstrdup(r->pool, (char*) lpvBuffer); } if (AppendLogToErrors) ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_INFO, r, "ISAPI %s: %s", cid->r->filename, (char*) lpvBuffer); return TRUE; /* We don't support all this async I/O, Microsoft-specific stuff */ case 1005: /* HSE_REQ_IO_COMPLETION */ case 1006: /* HSE_REQ_TRANSMIT_FILE */ if (LogNotSupported) ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, r, "ISAPI asynchronous I/O not supported: %s", r->filename); SetLastError(ERROR_INVALID_PARAMETER); return FALSE; case 1007: /* HSE_REQ_REFRESH_ISAPI_ACL */ /* Since we don't override the user ID and access, we can't reset. */ if (LogNotSupported) ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, r, "ISAPI ServerSupportFunction " "HSE_REQ_REFRESH_ISAPI_ACL " "is not supported: %s", r->filename); SetLastError(ERROR_INVALID_PARAMETER); return FALSE; case 1008: /* HSE_REQ_IS_KEEP_CONN */ *((LPBOOL) lpvBuffer) = (r->connection->keepalive == 1); return TRUE; case 1010: /* HSE_REQ_ASYNC_READ_CLIENT */ if (LogNotSupported) ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, r, "ISAPI asynchronous I/O not supported: %s", r->filename); SetLastError(ERROR_INVALID_PARAMETER); return FALSE; case 1011: /* HSE_REQ_GET_IMPERSONATION_TOKEN Added in ISAPI 4.0 */ if (LogNotSupported) ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, r, "ISAPI ServerSupportFunction " "HSE_REQ_GET_IMPERSONATION_TOKEN " "is not supported: %s", r->filename); SetLastError(ERROR_INVALID_PARAMETER); return FALSE; #ifdef HSE_REQ_MAP_URL_TO_PATH_EX case 1012: /* HSE_REQ_MAP_URL_TO_PATH_EX */ { /* Map a URL to a filename */ LPHSE_URL_MAPEX_INFO info = (LPHSE_URL_MAPEX_INFO) lpdwDataType; char* test_uri = ap_pstrndup(r->pool, (char *)lpvBuffer, *lpdwSize); subreq = ap_sub_req_lookup_uri(test_uri, r); info->cchMatchingURL = strlen(test_uri); info->cchMatchingPath = ap_cpystrn(info->lpszPath, subreq->filename, MAX_PATH) - info->lpszPath; /* Mapping started with assuming both strings matched. * Now roll on the path_info as a mismatch and handle * terminating slashes for directory matches. */ if (subreq->path_info && *subreq->path_info) { ap_cpystrn(info->lpszPath + info->cchMatchingPath, subreq->path_info, MAX_PATH - info->cchMatchingPath); info->cchMatchingURL -= strlen(subreq->path_info); if (S_ISDIR(subreq->finfo.st_mode) && info->cchMatchingPath < MAX_PATH - 1) { /* roll forward over path_info's first slash */ ++info->cchMatchingPath; ++info->cchMatchingURL; } } else if (S_ISDIR(subreq->finfo.st_mode) && info->cchMatchingPath < MAX_PATH - 1) { /* Add a trailing slash for directory */ info->lpszPath[info->cchMatchingPath++] = '/'; info->lpszPath[info->cchMatchingPath] = '\0'; } /* If the matched isn't a file, roll match back to the prior slash */ if (!subreq->finfo.st_mode) { while (info->cchMatchingPath && info->cchMatchingURL) { if (info->lpszPath[info->cchMatchingPath - 1] == '/') break; --info->cchMatchingPath; --info->cchMatchingURL; } } /* Paths returned with back slashes */ for (test_uri = info->lpszPath; *test_uri; ++test_uri) if (*test_uri == '/') *test_uri = '\\'; /* is a combination of: * HSE_URL_FLAGS_READ 0x001 Allow read * HSE_URL_FLAGS_WRITE 0x002 Allow write * HSE_URL_FLAGS_EXECUTE 0x004 Allow execute * HSE_URL_FLAGS_SSL 0x008 Require SSL * HSE_URL_FLAGS_DONT_CACHE 0x010 Don't cache (VRoot only) * HSE_URL_FLAGS_NEGO_CERT 0x020 Allow client SSL cert * HSE_URL_FLAGS_REQUIRE_CERT 0x040 Require client SSL cert * HSE_URL_FLAGS_MAP_CERT 0x080 Map client SSL cert to account * HSE_URL_FLAGS_SSL128 0x100 Require 128-bit SSL cert * HSE_URL_FLAGS_SCRIPT 0x200 Allow script execution * * XxX: As everywhere, EXEC flags could use some work... * and this could go further with more flags, as desired. */ info->dwFlags = (subreq->finfo.st_mode & _S_IREAD ? 0x001 : 0) | (subreq->finfo.st_mode & _S_IWRITE ? 0x002 : 0) | (subreq->finfo.st_mode & _S_IEXEC ? 0x204 : 0); return TRUE; } #endif case 1014: /* HSE_REQ_ABORTIVE_CLOSE */ if (LogNotSupported) ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, r, "ISAPI ServerSupportFunction HSE_REQ_ABORTIVE_CLOSE" " is not supported: %s", r->filename); SetLastError(ERROR_INVALID_PARAMETER); return FALSE; case 1015: /* HSE_REQ_GET_CERT_INFO_EX Added in ISAPI 4.0 */ if (LogNotSupported) ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, r, "ISAPI ServerSupportFunction " "HSE_REQ_GET_CERT_INFO_EX " "is not supported: %s", r->filename); SetLastError(ERROR_INVALID_PARAMETER); return FALSE; #ifdef HSE_REQ_SEND_RESPONSE_HEADER_EX case 1016: /* HSE_REQ_SEND_RESPONSE_HEADER_EX Added in ISAPI 4.0 */ { LPHSE_SEND_HEADER_EX_INFO shi = (LPHSE_SEND_HEADER_EX_INFO) lpvBuffer; /* XXX: ignore shi->fKeepConn? We shouldn't need the advise */ /* r->connection->keepalive = shi->fKeepConn; */ return SendResponseHeaderEx(cid, shi->pszStatus, shi->pszHeader, shi->cchStatus, shi->cchHeader); } #endif case 1017: /* HSE_REQ_CLOSE_CONNECTION Added after ISAPI 4.0 */ if (LogNotSupported) ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, r, "ISAPI ServerSupportFunction " "HSE_REQ_CLOSE_CONNECTION " "is not supported: %s", r->filename); SetLastError(ERROR_INVALID_PARAMETER); return FALSE; case 1018: /* HSE_REQ_IS_CONNECTED Added after ISAPI 4.0 */ /* Returns True if client is connected c.f. MSKB Q188346 * XXX: That statement is very ambigious... assuming the * identical return mechanism as HSE_REQ_IS_KEEP_CONN. */ *((LPBOOL) lpvBuffer) = (r->connection->aborted == 0); return TRUE; case 1020: /* HSE_REQ_EXTENSION_TRIGGER Added after ISAPI 4.0 */ /* Undocumented - defined by the Microsoft Jan '00 Platform SDK */ if (LogNotSupported) ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, r, "ISAPI ServerSupportFunction " "HSE_REQ_EXTENSION_TRIGGER " "is not supported: %s", r->filename); SetLastError(ERROR_INVALID_PARAMETER); return FALSE; default: if (LogNotSupported) ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, r, "ISAPI ServerSupportFunction (%d) not supported: " "%s", dwHSERequest, r->filename); SetLastError(ERROR_INVALID_PARAMETER); return FALSE; } }
/* * Make a password record from the given information. A zero return * indicates success; failure means that the output buffer contains an * error message instead. */ static int mkrecord(char *user, char *record, size_t rlen, char *passwd, int alg) { char *pw; char cpw[120]; char pwin[MAX_STRING_LEN]; char pwv[MAX_STRING_LEN]; char salt[9]; if (passwd != NULL) { pw = passwd; } else { #ifdef TPF fprintf(stderr, "Invalid entry. The -b option is required on TPF.\n"); return usage(); #else if (ap_getpass("New password: "******"password too long (>%lu)", (unsigned long) (sizeof(pwin) - 1)); return ERR_OVERFLOW; } ap_getpass("Re-type new password: "******"password verification error", (rlen - 1)); return ERR_PWMISMATCH; } pw = pwin; memset(pwv, '\0', sizeof(pwin)); #endif /* TPF */ } switch (alg) { case ALG_APSHA: /* XXX cpw >= 28 + strlen(sha1) chars - fixed len SHA */ ap_sha1_base64(pw,strlen(pw),cpw); break; case ALG_APMD5: (void) srand((int) time((time_t *) NULL)); ap_to64(&salt[0], rand(), 8); salt[8] = '\0'; ap_MD5Encode((const unsigned char *)pw, (const unsigned char *)salt, cpw, sizeof(cpw)); break; case ALG_PLAIN: /* XXX this len limitation is not in sync with any HTTPd len. */ ap_cpystrn(cpw,pw,sizeof(cpw)); break; case ALG_CRYPT: default: (void) srand((int) time((time_t *) NULL)); ap_to64(&salt[0], rand(), 8); salt[8] = '\0'; ap_cpystrn(cpw, (char *)crypt(pw, salt), sizeof(cpw) - 1); break; } memset(pw, '\0', strlen(pw)); /* * Check to see if the buffer is large enough to hold the username, * hash, and delimiters. */ if ((strlen(user) + 1 + strlen(cpw)) > (rlen - 1)) { ap_cpystrn(record, "resultant record too long", (rlen - 1)); return ERR_OVERFLOW; } strcpy(record, user); strcat(record, ":"); strcat(record, cpw); return 0; }