void exec_openstdy() { char filename[MAXPATHLEN]; char password[PASSWORDLEN]; StdyFile *stdy; get_nstring(filename, sizeof(filename)); get_nstring(password, sizeof(password)); if (cur_cli -> stdy) longjmp(error_ret, SJ3_StdyAlreadyOpened); if (make_full_path(filename, sizeof(filename))) longjmp(error_ret, SJ3_TooLongParameter); if (!(stdy = openstdy(filename, password))) longjmp(error_ret, serv_errno); cur_cli -> stdy = stdy; put_int(SJ3_NormalEnd); }
/* dissect a request body. see AJPv13.html, but the idea is that these * packets, unlike all other packets, have no type field. you just * sort of have to know that they're coming based on the previous * packets. */ static void display_req_body(tvbuff_t *tvb, proto_tree *ajp13_tree, ajp13_conv_data* cd) { /*printf("ajp13:display_req_body()\n");*/ /* * In a resued connection this is never reset. */ guint16 content_length; guint16 packet_length; guint8 body_bytes[128*1024]; /* DANGER WILL ROBINSON */ int pos = 0; guint16 body_len; /* MAGIC */ proto_tree_add_item(ajp13_tree, hf_ajp13_magic, tvb, pos, 2, 0); pos+=2; /* PACKET LENGTH */ packet_length = tvb_get_ntohs(tvb, pos); proto_tree_add_item(ajp13_tree, hf_ajp13_len, tvb, pos, 2, 0); pos+=2; if (packet_length == 0) { /* * We've got an empty packet: * 0x12 0x34 0x00 0x00 * It signals that there is no more data in the body */ cd->content_length = 0; return; } /* BODY (AS STRING) */ content_length = tvb_get_ntohs( tvb, pos); cd->content_length -= content_length; body_len = get_nstring(tvb, pos, body_bytes, sizeof body_bytes); proto_tree_add_item(ajp13_tree, hf_ajp13_data, tvb, pos+2, body_len-1, 0); }
/* note that even if ajp13_tree is null on the first pass, we still * need to dissect the packet in order to determine if there is a * content-length, and thus if there is a subsequent automatic * request-body transmitted in the next request packet. if there is a * content-length, we record the fact in the conversation context. * ref the top of this file for comments explaining the multi-pass * thing. */ static void display_req_forward(tvbuff_t *tvb, packet_info *pinfo, proto_tree *ajp13_tree, ajp13_conv_data* cd) { int pos = 0; guint8 meth; guint8 cod; guint8 ver[1024]; guint16 ver_len; guint8 uri[4096]; guint16 uri_len; guint8 raddr[4096]; guint16 raddr_len; guint8 rhost[4096]; guint16 rhost_len; guint8 srv[4096]; guint16 srv_len; guint nhdr; guint i; if (ajp13_tree) proto_tree_add_item(ajp13_tree, hf_ajp13_magic, tvb, pos, 2, 0); pos+=2; if (ajp13_tree) proto_tree_add_item(ajp13_tree, hf_ajp13_len, tvb, pos, 2, 0); pos+=2; /* PACKET CODE */ cod = tvb_get_guint8(tvb, 4); if (ajp13_tree) { const gchar* msg_code = NULL; char *mcode_buf; msg_code = val_to_str(cod, mtype_codes, "UNKNOWN"); mcode_buf=ep_strdup_printf("(%d) %s", cod, msg_code); proto_tree_add_string(ajp13_tree, hf_ajp13_code, tvb, pos, 1, mcode_buf); } pos+=1; if ( cod == 10 ) { col_append_str(pinfo->cinfo, COL_INFO, "CPING" ); return; } /* HTTP METHOD (ENCODED AS INTEGER) */ { const gchar* meth_code = NULL; meth = tvb_get_guint8(tvb, pos); meth_code = val_to_str(meth, http_method_codes, "UNKNOWN"); if (ajp13_tree) { char *mcode_buf; mcode_buf=ep_strdup_printf("(%d) %s", meth, meth_code); proto_tree_add_string(ajp13_tree, hf_ajp13_method, tvb, pos, 1, mcode_buf); } col_append_str(pinfo->cinfo, COL_INFO, meth_code); pos+=1; } /* HTTP VERSION STRING */ ver_len = get_nstring(tvb, pos, ver, sizeof ver); pos+=2; /* skip over size */ if (ajp13_tree) proto_tree_add_item(ajp13_tree, hf_ajp13_ver, tvb, pos, ver_len, 0); pos=pos+ver_len; /* skip over chars + trailing null */ /* URI */ uri_len = get_nstring(tvb, pos, uri, sizeof uri); pos+=2; /* skip over size */ if (ajp13_tree) proto_tree_add_item(ajp13_tree, hf_ajp13_uri, tvb, pos, uri_len, 0); pos=pos+uri_len; /* skip over chars + trailing null */ if(check_col(pinfo->cinfo, COL_INFO)) col_append_fstr(pinfo->cinfo, COL_INFO, " %s %s", uri, ver); /* REMOTE ADDRESS */ raddr_len = get_nstring(tvb, pos, raddr, sizeof raddr); pos+=2; /* skip over size */ if (ajp13_tree) proto_tree_add_item(ajp13_tree, hf_ajp13_raddr, tvb, pos, raddr_len, 0); pos=pos+raddr_len; /* skip over chars + trailing null */ /* REMOTE HOST */ rhost_len = get_nstring(tvb, pos, rhost, sizeof rhost); pos+=2; /* skip over size */ if (ajp13_tree) proto_tree_add_item(ajp13_tree, hf_ajp13_rhost, tvb, pos, rhost_len, 0); pos=pos+rhost_len; /* skip over chars + trailing null */ /* SERVER NAME */ srv_len = get_nstring(tvb, pos, srv, sizeof srv); pos+=2; /* skip over size */ if (ajp13_tree) proto_tree_add_item(ajp13_tree, hf_ajp13_srv, tvb, pos, srv_len, 0); pos=pos+srv_len; /* skip over chars + trailing null */ /* SERVER PORT */ if (ajp13_tree) proto_tree_add_item(ajp13_tree, hf_ajp13_port, tvb, pos, 2, 0); pos+=2; /* IS SSL? */ if (ajp13_tree) proto_tree_add_item(ajp13_tree, hf_ajp13_sslp, tvb, pos, 1, 0); pos+=1; /* NUM HEADERS */ nhdr = tvb_get_ntohs(tvb, pos); if (ajp13_tree) proto_tree_add_item(ajp13_tree, hf_ajp13_nhdr, tvb, pos, 2, 0); pos+=2; cd->content_length = 0; /* HEADERS */ for(i=0; i<nhdr; i++) { guint8 hcd; guint8 hid; int orig_pos = pos; const gchar* hname = NULL; int dp = 0; int cl = 0; guint8 *hval; guint16 hval_len; /* HEADER CODE/NAME */ hcd = tvb_get_guint8(tvb, pos); if (hcd == 0xA0) { pos+=1; hid = tvb_get_guint8(tvb, pos); pos+=1; hname = val_to_str(hid, req_header_codes, "UNKNOWN"); if (hid == 0x08) cl = 1; } else { guint8 *hname_bytes; int hname_len; hname_bytes=ep_alloc(1024); hname_len = get_nstring(tvb, pos, hname_bytes, 1024); pos+=hname_len+2; hname = (gchar*)hname_bytes; } dp = pos-orig_pos; /* HEADER VALUE */ orig_pos = pos; hval=ep_alloc(8192); hval_len = get_nstring(tvb, pos, hval, 8192); pos+=hval_len+2; dp = pos - orig_pos; if (ajp13_tree) { proto_tree_add_string_format(ajp13_tree, hf_ajp13_hval, tvb, orig_pos, dp, hname, "%s: %s", hname, hval); } if (cl) { cl = atoi(hval); cd->content_length = cl; } } }
/* dissect a response. more work to do here. */ static void display_rsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *ajp13_tree, ajp13_conv_data* cd) { const gchar* msg_code = NULL; int pos = 0; guint8 mcode = 0; char *mcode_buf; int i; /* MAGIC */ if (ajp13_tree) proto_tree_add_item(ajp13_tree, hf_ajp13_magic, tvb, pos, 2, 0); pos+=2; /* PDU LENGTH */ if (ajp13_tree) proto_tree_add_item(ajp13_tree, hf_ajp13_len, tvb, pos, 2, 0); pos+=2; /* MESSAGE TYPE CODE */ mcode = tvb_get_guint8(tvb, pos); msg_code = val_to_str(mcode, mtype_codes, "UNKNOWN"); mcode_buf=ep_strdup_printf("(%d) %s", mcode, msg_code); if (ajp13_tree) proto_tree_add_string(ajp13_tree, hf_ajp13_code, tvb, pos, 1, mcode_buf); pos+=1; col_append_str(pinfo->cinfo, COL_INFO, msg_code); if (mcode == 5) { if (ajp13_tree) proto_tree_add_item(ajp13_tree, hf_ajp13_reusep, tvb, pos, 1, 0); pos+=1; } else if (mcode == 4) { guint8 rsmsg_bytes[8*1024]; /* DANGER WILL ROBINSON */ guint16 rsmsg_len; guint16 nhdr; guint16 rcode_num; /* HTTP RESPONSE STATUS CODE */ rcode_num = tvb_get_ntohs(tvb, pos); if (ajp13_tree) proto_tree_add_item(ajp13_tree, hf_ajp13_rstatus, tvb, pos, 2, 0); pos+=2; if(check_col(pinfo->cinfo, COL_INFO)) col_append_fstr(pinfo->cinfo, COL_INFO, ":%d", rcode_num); /* HTTP RESPONSE STATUS MESSAGE */ rsmsg_len = get_nstring(tvb, pos, rsmsg_bytes, sizeof rsmsg_bytes); pos+=2; if (ajp13_tree) proto_tree_add_item(ajp13_tree, hf_ajp13_rsmsg, tvb, pos, rsmsg_len, 0); pos+=rsmsg_len; /* dangerous assumption that we can just %s out raw bytes */ if(check_col(pinfo->cinfo, COL_INFO)) col_append_fstr(pinfo->cinfo, COL_INFO, " %s", rsmsg_bytes); /* NUMBER OF HEADERS */ nhdr = tvb_get_ntohs(tvb, pos); if (ajp13_tree) proto_tree_add_item(ajp13_tree, hf_ajp13_nhdr, tvb, pos, 2, 0); pos+=2; /* HEADERS */ for(i=0; i<nhdr; i++) { guint8 hcd; guint8 hid; guint8 hval[8192]; guint16 hval_len; int orig_pos = pos; const gchar* hname = NULL; int dp = 0; int cl = 0; guint8 hname_bytes[1024]; /* HEADER CODE/NAME */ hcd = tvb_get_guint8(tvb, pos); if (hcd == 0xA0) { pos+=1; hid = tvb_get_guint8(tvb, pos); pos+=1; hname = val_to_str(hid, rsp_header_codes, "UNKNOWN"); /* Content-Length header (encoded by 0x08) is special */ if (hid == 0x08) cl = 1; } else { int hname_len = get_nstring(tvb, pos, hname_bytes, sizeof hname_bytes); pos+=hname_len+2; hname = (gchar*)hname_bytes; /* VERY EVIL */ } dp = pos-orig_pos; /* HEADER VALUE */ orig_pos = pos; hval_len = get_nstring(tvb, pos, hval, sizeof hval); pos+=hval_len+2; dp = pos - orig_pos; if (ajp13_tree) { gchar *hname_value; hname_value=ep_alloc(512); g_snprintf(hname_value, 512, "%s : %s", hname, hval); proto_tree_add_string(ajp13_tree, hf_ajp13_hval, tvb, orig_pos, dp, hname_value); } } } else if (mcode == 6) { guint16 rlen; rlen = tvb_get_ntohs(tvb, pos); cd->content_length = rlen; if (ajp13_tree) proto_tree_add_item(ajp13_tree, hf_ajp13_rlen, tvb, pos, 2, 0); pos+=2; } else if ( mcode == 9 ) { } else { /* MESSAGE DATA (COPOUT) */ if (ajp13_tree) proto_tree_add_item(ajp13_tree, hf_ajp13_data, tvb, pos+2, -1, 0); } }
void exec_opendict() { char filename[MAXPATHLEN]; char password[PASSWORDLEN]; DICT *dict; DICTL *dictl, *dltp, *tmp; get_nstring(filename, sizeof(filename)); get_nstring(password, sizeof(password)); if (!work_base) longjmp(error_ret, SJ3_NotConnected); if (make_full_path(filename, sizeof(filename))) longjmp(error_ret, SJ3_TooLongParameter); if (!(dict = (DICT *)opendict(filename, password))) longjmp(error_ret, serv_errno); if (!dictlist && global_work_base) { DICTL *b_dictl = NULL; dltp = global_work_base -> Jdictlist; dictl = NULL; while (dltp) { dictl = (DICTL *)malloc(sizeof *dictl); if (!dictl) { for (tmp = dictlist; tmp; tmp->next) free(tmp); dictlist = NULL; } if (!dictlist) dictlist = dictl; dictl->dict = dltp->dict; ((DictFile *)(dictl -> dict))->refcnt++; dictl->next = NULL; if (b_dictl) b_dictl->next = dictl; b_dictl = dictl; dltp = dltp->next; } } for (dltp = dictlist; dltp && dltp->dict != dict; dltp = dltp->next) ; if (!dltp) { if (!(dictl = (DICTL *)malloc(sizeof *dictl))) { closedict((DictFile *)dict); longjmp(error_ret, SJ3_NotEnoughMemory); } dictl -> dict = dict; dictl -> next = dictlist; dictlist = dictl; } if (cur_cli -> work -> lock == cur_cli -> fd) { if (dict -> maxunit != 0) lock_dict((DictFile *)dict, cur_cli -> fd); } put_int(SJ3_NormalEnd); put_int((int)dict->dicid); }
void exec_connect() { int version; char hostname[MAXHOSTNAMELEN]; char username[MAXLOGNAME]; char progname[MAXPATHLEN]; WorkArea *wp; sj3_ugid ugid; version = get_int(); get_nstring(hostname, sizeof(hostname)); get_nstring(username, sizeof(username)); get_nstring(progname, sizeof(progname)); if (cur_cli -> work) longjmp(error_ret, SJ3_AlreadyConnected); if (version < 0) longjmp(error_ret, SJ3_DifferentVersion); if (hostname[0] == '\0') longjmp(error_ret, SJ3_NoHostName); if (username[0] == '\0') longjmp(error_ret, SJ3_NoUserName); if (!check_user(username, hostname)) longjmp(error_ret, SJ3_NotAllowedUser); if (!(wp = alloc_workarea())) longjmp(error_ret, SJ3_NotEnoughMemory); if (priv_getugid(username, &ugid)) { struct sockaddr addr; uid_t euid; gid_t egid; int len = sizeof(addr); if (getsockname(cur_client->fd, &addr, &len) < 0) perror("getsockname"); if (strict_auth_enable) { getpeereid(cur_client->fd, &euid, &egid); if (ugid.uid != euid || ugid.gid != egid) { longjmp(error_ret, SJ3_NotAllowedUser); } } cur_cli -> uid = ugid.uid; } else longjmp(error_ret, SJ3_NotAllowedUser); cur_cli -> version = version; strlcpy(cur_cli -> host, hostname, sizeof(cur_cli -> host)); strlcpy(cur_cli -> user, username, sizeof(cur_cli -> user)); strlcpy(cur_cli -> prog, progname, sizeof(cur_cli -> prog)); rmemcpy(cur_cli -> def_char, defaultchar, 2); cur_cli -> work = wp; if (version == 1) put_int(SJ3_NormalEnd); else put_int((-SJ3SERV_VERSION_NO)); logging_out("connection established on %d (%s, %s, %s)", cur_cli -> fd, hostname, username, progname); }