Esempio n. 1
0
/*
 * Receiving side of the chat window.  
 * This does JavaScript writes to
 * other divs whenever it refreshes and finds new data.
 */
void chat_recv(void) {
	char buf[SIZ];
	char cl_user[SIZ];

	serv_printf("RCHT poll|%d", WC->last_chat_seq);
	serv_getln(buf, sizeof buf);
	if (buf[0] == '1') {
		WC->last_chat_seq = extract_int(&buf[4], 0);
		extract_token(cl_user, &buf[4], 2, '|', sizeof cl_user);

		/* who is speaking ... */
		if (strcasecmp(cl_user, WC->last_chat_user)) {
			wc_printf("<br>\n");
			if (!strcasecmp(cl_user, ChrPtr(WC->wc_fullname))) {
				wc_printf("<span class=\"chat_myname_class\">");
			}
			else {
				wc_printf("<span class=\"chat_notmyname_class\">");
			}
			escputs(cl_user);
			strcpy(WC->last_chat_user, cl_user);

			wc_printf(": </span>");
		}
		else {
			wc_printf("&nbsp;&nbsp;&nbsp;");
		}

		/* what did they say ... */
		wc_printf("<span class=\"chat_text_class\">");
		while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) {
			escputs(buf);
		}
		wc_printf("<br></span>\n");
	}
}
Esempio n. 2
0
/*
 * Determine whether a given Internet address belongs to the current user
 */
int CtdlIsMe(char *addr, int addr_buf_len)
{
	recptypes *recp;
	int i;

	recp = validate_recipients(addr, NULL, 0);
	if (recp == NULL) return(0);

	if (recp->num_local == 0) {
		free_recipients(recp);
		return(0);
	}

	for (i=0; i<recp->num_local; ++i) {
		extract_token(addr, recp->recp_local, i, '|', addr_buf_len);
		if (!strcasecmp(addr, CC->user.fullname)) {
			free_recipients(recp);
			return(1);
		}
	}

	free_recipients(recp);
	return(0);
}
Esempio n. 3
0
void load_plugin_filters(int link_type)
{
  struct plugins_list_entry *list = plugins_list;

  while (list) {
    if ((*list->type.func)) {

      /* compiling aggregation filter if needed */
      if (list->cfg.a_filter) {
	pcap_t *dev_desc;
	bpf_u_int32 localnet, netmask = 0;  /* pcap library stuff */
	char errbuf[PCAP_ERRBUF_SIZE], *count_token;
	int idx = 0;

	dev_desc = pcap_open_dead(link_type, 128); /* 128 bytes should be long enough */

	if (config.dev) pcap_lookupnet(config.dev, &localnet, &netmask, errbuf);

	list->cfg.bpfp_a_table[idx] = malloc(sizeof(struct bpf_program));
	while ( (count_token = extract_token(&list->cfg.a_filter, ',')) && idx < AGG_FILTER_ENTRIES ) {
	  if (pcap_compile(dev_desc, list->cfg.bpfp_a_table[idx], count_token, 0, netmask) < 0) {
	    Log(LOG_WARNING, "WARN: %s\nWARN ( %s/%s ): aggregation filter disabled.\n",
	    				pcap_geterr(dev_desc), list->cfg.name, list->cfg.type);
	  }
	  else {
	    idx++;
	    list->cfg.bpfp_a_table[idx] = malloc(sizeof(struct bpf_program));
	  }
	}

	list->cfg.bpfp_a_num = idx;
      }
    }
    list = list->next;
  }
}
Esempio n. 4
0
static int parse_media(char *start, char *end, struct sdp_media *output) {
	char *ep;
	str s, *sp;

	EXTRACT_TOKEN(media_type);
	EXTRACT_TOKEN(port);
	EXTRACT_TOKEN(transport);
	str_init_len(&output->formats, start, end - start);

	output->port_num = strtol(output->port.s, &ep, 10);
	if (ep == output->port.s)
		return -1;
	if (output->port_num < 0 || output->port_num > 0xffff)
		return -1;

	if (*ep == '/') {
		output->port_count = atoi(ep + 1);
		if (output->port_count <= 0)
			return -1;
		if (output->port_count > 10) /* unsupported */
			return -1;
	}
	else
		output->port_count = 1;

	/* to split the "formats" list into tokens, we abuse some vars */
	start = output->formats.s;
	end = start + output->formats.len;
	while (!extract_token(&start, end, &s)) {
		sp = g_slice_alloc(sizeof(*sp));
		*sp = s;
		g_queue_push_tail(&output->format_list, sp);
	}

	return 0;
}
Esempio n. 5
0
/* Special decoder for syscheck
 * Not using the default decoding lib for simplicity
 * and to be less resource intensive
 */
int DecodeSyscheck(Eventinfo *lf)
{
    const char *c_sum;
    char *f_name;

#ifdef SQLITE_ENABLED
    char *p;
    char stmt[OS_MAXSTR + 1];
    sqlite3_stmt *res;
    int error = 0;
    int rec_count = 0;
    const char *tail;
#endif // SQLITE_ENABLED

    /* Every syscheck message must be in the following format:
     * checksum filename
     */
    f_name = strchr(lf->log, ' ');
    if (f_name == NULL) {
        /* If we don't have a valid syscheck message, it may be
         * a database completed message
         */
        if (strcmp(lf->log, HC_SK_DB_COMPLETED) == 0) {
            DB_SetCompleted(lf);
            return (0);
        }

        merror(SK_INV_MSG, ARGV0);
        return (0);
    }

    /* Zero to get the check sum */
    *f_name = '\0';
    f_name++;

    /* Get diff */
    lf->data = strchr(f_name, '\n');
    if (lf->data) {
        *lf->data = '\0';
        lf->data++;
    } else {
        lf->data = NULL;
    }

    /* Check if file is supposed to be ignored */
    if (Config.syscheck_ignore) {
        char **ff_ig = Config.syscheck_ignore;

        while (*ff_ig) {
            if (strncasecmp(*ff_ig, f_name, strlen(*ff_ig)) == 0) {
                lf->data = NULL;
                return (0);
            }

            ff_ig++;
        }
    }

    /* Checksum is at the beginning of the log */
    c_sum = lf->log;

    /* Extract the MD5 hash and search for it in the allowlist
     * Sample message:
     * 0:0:0:0:78f5c869675b1d09ddad870adad073f9:bd6c8d7a58b462aac86475e59af0e22954039c50
     */
#ifdef SQLITE_ENABLED
    if (Config.md5_allowlist)  {
        extern sqlite3 *conn;
        if ((p = extract_token(c_sum, ":", 4))) {
            if (!validate_md5(p)) { /* Never trust input from other origin */
                merror("%s: Not a valid MD5 hash: '%s'", ARGV0, p);
                return(0);
            }
            debug1("%s: Checking MD5 '%s' in %s", ARGV0, p, Config.md5_allowlist);
            sprintf(stmt, "select md5sum from files where md5sum = \"%s\"", p);
            error = sqlite3_prepare_v2(conn, stmt, 1000, &res, &tail);
            if (error == SQLITE_OK) {
                while (sqlite3_step(res) == SQLITE_ROW) {
                    rec_count++;
                }
                if (rec_count) {    
                    sqlite3_finalize(res);
                    //sqlite3_close(conn);
                    merror(MD5_NOT_CHECKED, ARGV0, p);
                    return(0);
                }
            }
            sqlite3_finalize(res);
        }
    }
#endif
 

    /* Search for file changes */
    return (DB_Search(f_name, c_sum, lf));
}
Esempio n. 6
0
//
// Implements the ARTICLE, HEAD, BODY, and STAT commands.
// (These commands all accept the same parameters; they differ only in how they output the retrieved message.)
//
void nntp_article(const char *cmd) {
	if (CtdlAccessCheck(ac_logged_in_or_guest)) return;

	citnntp *nntpstate = (citnntp *) CC->session_specific_data;
	char which_command[16];
	int acmd = 0;
	char requested_article[256];
	long requested_msgnum = 0;
	char *lb, *rb = NULL;
	int must_change_currently_selected_article = 0;

	// We're going to store one of these values in the variable 'acmd' so that
	// we can quickly check later which version of the output we want.
	enum {
		ARTICLE,
		HEAD,
		BODY,
		STAT
	};

	extract_token(which_command, cmd, 0, ' ', sizeof which_command);

	if (!strcasecmp(which_command, "article")) {
		acmd = ARTICLE;
	}
	else if (!strcasecmp(which_command, "head")) {
		acmd = HEAD;
	}
	else if (!strcasecmp(which_command, "body")) {
		acmd = BODY;
	}
	else if (!strcasecmp(which_command, "stat")) {
		acmd = STAT;
	}
	else {
		cprintf("500 I'm afraid I can't do that.\r\n");
		return;
	}

	// Which NNTP command was issued, determines whether we will fetch headers, body, or both.
	int			headers_only = HEADERS_ALL;
	if (acmd == HEAD)	headers_only = HEADERS_FAST;
	else if (acmd == BODY)	headers_only = HEADERS_NONE;
	else if (acmd == STAT)	headers_only = HEADERS_FAST;

	// now figure out what the client is asking for.
	extract_token(requested_article, cmd, 1, ' ', sizeof requested_article);
	lb = strchr(requested_article, '<');
	rb = strchr(requested_article, '>');
	requested_msgnum = atol(requested_article);

	// If no article number or message-id is specified, the client wants the "currently selected article"
	if (IsEmptyStr(requested_article)) {
		if (nntpstate->current_article_number < 1) {
			cprintf("420 No current article selected\r\n");
			return;
		}
		requested_msgnum = nntpstate->current_article_number;
		must_change_currently_selected_article = 1;
		// got it -- now fall through and keep going
	}

	// If the requested article is numeric, it maps directly to a message number.  Good.
	else if (requested_msgnum > 0) {
		must_change_currently_selected_article = 1;
		// good -- fall through and keep going
	}

	// If the requested article has angle brackets, the client wants a specific message-id.
	// We don't know how to do that yet.
	else if ( (lb != NULL) && (rb != NULL) && (lb < rb) ) {
		must_change_currently_selected_article = 0;
		cprintf("500 I don't know how to fetch by message-id yet.\r\n");	// FIXME
		return;
	}

	// Anything else is noncompliant gobbledygook and should die in a car fire.
	else {
		must_change_currently_selected_article = 0;
		cprintf("500 syntax error\r\n");
		return;
	}

	// At this point we know the message number of the "article" being requested.
	// We have an awesome API call that does all the heavy lifting for us.
	char *fetched_message_id = NULL;
	CC->redirect_buffer = NewStrBufPlain(NULL, SIZ);
	int fetch = CtdlOutputMsg(requested_msgnum,
			MT_RFC822,		// output in RFC822 format ... sort of
			headers_only,		// headers, body, or both?
			0,			// don't do Citadel protocol responses
			1,			// CRLF newlines
			NULL,			// teh whole thing, not just a section
			0,			// no flags yet ... maybe new ones for Path: etc ?
			NULL,
			NULL,
			&fetched_message_id	// extract the message ID from the message as we go...
	);
	StrBuf *msgtext = CC->redirect_buffer;
	CC->redirect_buffer = NULL;

	if (fetch != om_ok) {
		cprintf("423 no article with that number\r\n");
		FreeStrBuf(&msgtext);
		return;
	}

	// RFC3977 6.2.1.2 specifes conditions under which the "currently selected article"
	// MUST or MUST NOT be set to the message we just referenced.
	if (must_change_currently_selected_article) {
		nntpstate->current_article_number = requested_msgnum;
	}

	// Now give the client what it asked for.
	if (acmd == ARTICLE) {
		cprintf("220 %ld <%s>\r\n", requested_msgnum, fetched_message_id);
	}
	if (acmd == HEAD) {
		cprintf("221 %ld <%s>\r\n", requested_msgnum, fetched_message_id);
	}
	if (acmd == BODY) {
		cprintf("222 %ld <%s>\r\n", requested_msgnum, fetched_message_id);
	}
	if (acmd == STAT) {
		cprintf("223 %ld <%s>\r\n", requested_msgnum, fetched_message_id);
		FreeStrBuf(&msgtext);
		return;
	}

	client_write(SKEY(msgtext));
	cprintf(".\r\n");			// this protocol uses a dot terminator
	FreeStrBuf(&msgtext);
	if (fetched_message_id) free(fetched_message_id);
}
Esempio n. 7
0
/*
 * Finalize an OpenID authentication
 */
void cmd_oidf(char *argbuf) {
	long len;
	char buf[2048];
	char thiskey[1024];
	char thisdata[1024];
	HashList *keys = NULL;
	const char *Key;
	void *Value;
	ctdl_openid *oiddata = (ctdl_openid *) CC->openid_data;

	if (CtdlGetConfigInt("c_disable_newu"))
	{
		cprintf("%d this system does not support openid.\n",
			ERROR + CMD_NOT_SUPPORTED);
		return;
	}
	if (oiddata == NULL) {
		cprintf("%d run OIDS first.\n", ERROR + INTERNAL_ERROR);
		return;
	}
	if (StrLength(oiddata->op_url) == 0){
		cprintf("%d No OpenID Endpoint URL has been obtained.\n", ERROR + ILLEGAL_VALUE);
		return;
	}
	keys = NewHash(1, NULL);
	if (!keys) {
		cprintf("%d NewHash() failed\n", ERROR + INTERNAL_ERROR);
		return;
	}
	cprintf("%d Transmit OpenID data now\n", START_CHAT_MODE);

	while (client_getln(buf, sizeof buf), strcmp(buf, "000")) {
		len = extract_token(thiskey, buf, 0, '|', sizeof thiskey);
		if (len < 0) {
			len = sizeof(thiskey) - 1;
		}
		extract_token(thisdata, buf, 1, '|', sizeof thisdata);
		Put(keys, thiskey, len, strdup(thisdata), NULL);
	}

	/* Check to see if this is a correct response.
	 * Start with verified=1 but then set it to 0 if anything looks wrong.
	 */
	oiddata->verified = 1;

	char *openid_ns = NULL;
	if (	(!GetHash(keys, "ns", 2, (void *) &openid_ns))
		|| (strcasecmp(openid_ns, "http://specs.openid.net/auth/2.0"))
	) {
		syslog(LOG_DEBUG, "This is not an an OpenID assertion");
		oiddata->verified = 0;
	}

	char *openid_mode = NULL;
	if (	(!GetHash(keys, "mode", 4, (void *) &openid_mode))
		|| (strcasecmp(openid_mode, "id_res"))
	) {
		oiddata->verified = 0;
	}

	char *openid_claimed_id = NULL;
	if (GetHash(keys, "claimed_id", 10, (void *) &openid_claimed_id)) {
		FreeStrBuf(&oiddata->claimed_id);
		oiddata->claimed_id = NewStrBufPlain(openid_claimed_id, -1);
		syslog(LOG_DEBUG, "Provider is asserting the Claimed ID '%s'", ChrPtr(oiddata->claimed_id));
	}

	/* Validate the assertion against the server */
	syslog(LOG_DEBUG, "Validating...");

	CURL *curl;
	CURLcode res;
	struct curl_httppost *formpost = NULL;
	struct curl_httppost *lastptr = NULL;
	char errmsg[1024] = "";
	StrBuf *ReplyBuf = NewStrBuf();

	curl_formadd(&formpost, &lastptr,
		CURLFORM_COPYNAME,	"openid.mode",
		CURLFORM_COPYCONTENTS,	"check_authentication",
		CURLFORM_END
	);

	HashPos *HashPos = GetNewHashPos(keys, 0);
	while (GetNextHashPos(keys, HashPos, &len, &Key, &Value) != 0) {
		if (strcasecmp(Key, "mode")) {
			char k_o_keyname[1024];
			snprintf(k_o_keyname, sizeof k_o_keyname, "openid.%s", (const char *)Key);
			curl_formadd(&formpost, &lastptr,
				CURLFORM_COPYNAME,	k_o_keyname,
				CURLFORM_COPYCONTENTS,	(char *)Value,
				CURLFORM_END
			);
		}
	}
	DeleteHashPos(&HashPos);

	curl = ctdl_openid_curl_easy_init(errmsg);
	curl_easy_setopt(curl, CURLOPT_URL, ChrPtr(oiddata->op_url));
	curl_easy_setopt(curl, CURLOPT_WRITEDATA, ReplyBuf);
	curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, CurlFillStrBuf_callback);
	curl_easy_setopt(curl, CURLOPT_HTTPPOST, formpost);

	res = curl_easy_perform(curl);
	if (res) {
		syslog(LOG_DEBUG, "cmd_oidf() libcurl error %d: %s", res, errmsg);
		oiddata->verified = 0;
	}
	curl_easy_cleanup(curl);
	curl_formfree(formpost);

	/* syslog(LOG_DEBUG, "Validation reply: \n%s", ChrPtr(ReplyBuf)); */
	if (cbmstrcasestr(ChrPtr(ReplyBuf), "is_valid:true") == NULL) {
		oiddata->verified = 0;
	}
	FreeStrBuf(&ReplyBuf);

	syslog(LOG_DEBUG, "OpenID authentication %s", (oiddata->verified ? "succeeded" : "failed") );

	/* Respond to the client */

	if (oiddata->verified) {

		/* If we were already logged in, attach the OpenID to the user's account */
		if (CC->logged_in) {
			if (attach_openid(&CC->user, oiddata->claimed_id) == 0) {
				cprintf("attach\n");
				syslog(LOG_DEBUG, "OpenID attach succeeded");
			}
			else {
				cprintf("fail\n");
				syslog(LOG_DEBUG, "OpenID attach failed");
			}
		}

		/* Otherwise, a user is attempting to log in using the verified OpenID */	
		else {
			/*
			 * Existing user who has claimed this OpenID?
			 *
			 * Note: if you think that sending the password back over the wire is insecure,
			 * check your assumptions.  If someone has successfully asserted an OpenID that
			 * is associated with the account, they already have password equivalency and can
			 * login, so they could just as easily change the password, etc.
			 */
			if (login_via_openid(oiddata->claimed_id) == 0) {
				cprintf("authenticate\n%s\n%s\n", CC->user.fullname, CC->user.password);
				logged_in_response();
				syslog(LOG_DEBUG, "Logged in using previously claimed OpenID");
			}

			/*
			 * If this system does not allow self-service new user registration, the
			 * remaining modes do not apply, so fail here and now.
			 */
			else if (CtdlGetConfigInt("c_disable_newu")) {
				cprintf("fail\n");
				syslog(LOG_DEBUG, "Creating user failed due to local policy");
			}

			/*
			 * New user whose OpenID is verified and Attribute Exchange gave us a name?
			 */
			else if (openid_create_user_via_ax(oiddata->claimed_id, keys) == 0) {
				cprintf("authenticate\n%s\n%s\n", CC->user.fullname, CC->user.password);
				logged_in_response();
				syslog(LOG_DEBUG, "Successfully auto-created new user");
			}

			/*
			 * OpenID is verified, but the desired username either was not specified or
			 * conflicts with an existing user.  Manual account creation is required.
			 */
			else {
				char *desired_name = NULL;
				cprintf("verify_only\n");
				cprintf("%s\n", ChrPtr(oiddata->claimed_id));
				if (GetHash(keys, "sreg.nickname", 13, (void *) &desired_name)) {
					cprintf("%s\n", desired_name);
				}
				else {
					cprintf("\n");
				}
				syslog(LOG_DEBUG, "The desired display name is already taken.");
			}
		}
	}
	else {
		cprintf("fail\n");
	}
	cprintf("000\n");

	if (oiddata->sreg_keys != NULL) {
		DeleteHash(&oiddata->sreg_keys);
		oiddata->sreg_keys = NULL;
	}
	oiddata->sreg_keys = keys;
}
Esempio n. 8
0
 inline int Gq_add_media_component_description(AAAMessage *msg,str sdpinvite,str sdp200,char *mline,int number,int tag)
 {
 	str data;
 	AAA_AVP_LIST list;
 	AAA_AVP *media_component_number,*media_type;
 	AAA_AVP *codec_data1,*codec_data2;
 	AAA_AVP *media_sub_component[Gq_Media_Sub_Components];
 	AAA_AVP *Max_DL,*Max_UL;
 	AAA_AVP *RR,*RS;
 	AAA_AVP *flow_status;
 	
 	bandwidth bwUL,bwDL;
 	
 	
 	char *ptr;
 	char port[Gq_MAX_Char];
 	int type,i,n,a;
 	char x[4];
	
 	
 	/*needed to use AAA_AVP-LIST!!*/
 	list.head=0;	 	
 	list.tail=0;
 	
 	
 	
 	/*media-component-number*/
 	 	
 	set_4bytes(x,number);	
 	media_component_number=cdpb.AAACreateAVP(AVP_IMS_Media_Component_Number,
 											AAA_AVP_FLAG_MANDATORY|AAA_AVP_FLAG_VENDOR_SPECIFIC,
 											IMS_vendor_id_3GPP,x,4,
 											AVP_DUPLICATE_DATA);

 	if (media_component_number!=NULL) 
 	{
 		AAAAddAVPToAVPList(&list,media_component_number);
 	} else {
 		LOG(L_INFO, ANSI_RED"INF:"M_NAME"Unable to create media_component_number AVP");
 		return 0;
 	}
 	
 	/*media-sub-component*/
 	
	n=Gq_create_add_media_subcomponents(&list,sdpinvite,sdp200,number,media_sub_component,tag);
 	if(n==-1)
 	{
 		LOG(L_INFO, ANSI_RED"INF:"M_NAME"Unable to create media_sub_components list AVP");
 		cdpb.AAAFreeAVP(&media_component_number);
 		list.head=0;
 		list.tail=0;	
 		return 0;
 	}
 	if (n==0) {
 		/*we don't create a Media Description for this media line*/
 		/*because answerer rejected the offer!*/
 		cdpb.AAAFreeAVP(&media_component_number);
 		list.head=0;
 		list.tail=0;
 		return 1;
 	}
 	
 	
 	
 	/*if n=-1 then its error*/
 	/*if n=0 is because answerer rejected this media offer*/
 	/*or offerer wanted it to be disabled*/
 	 	
 	/*media-type*/
 	 ptr=mline;
 	 ptr+=2; /*skip m=*/
 	 	 
 	 
 	 
 	 if (strncmp(ptr,"audio",5)==0)
 	 {
 	 	type=AVP_IMS_Media_Type_Audio;
 	 } else if(strncmp(ptr,"video",5)==0)
 	 {
 	 	type=AVP_IMS_Media_Type_Video;
 	 }else if(strncmp(ptr,"data",4)==0)
 	 {
 	 	type=AVP_IMS_Media_Type_Data;
 	 }else if(strncmp(ptr,"application",11)==0)
 	 {
 	 	type=AVP_IMS_Media_Type_Application;
 	 }else if(strncmp(ptr,"control",7)==0)
 	 {
 	 	type=AVP_IMS_Media_Type_Control;
 	 }else if(strncmp(ptr,"text",4)==0)
 	 {
 	 	type=AVP_IMS_Media_Type_Text;
 	 }else if(strncmp(ptr,"message",7)==0)
 	 {
 	 	type=AVP_IMS_Media_Type_Message;
 	 } else 
 	 {
 	 	type=AVP_IMS_Media_Type_Other;
 	 }
 	 
 	  	 
 	 set_4bytes(x,type);
 	 media_type=cdpb.AAACreateAVP(AVP_IMS_Media_Type,
 	 								AAA_AVP_FLAG_MANDATORY|AAA_AVP_FLAG_VENDOR_SPECIFIC,
 	 								IMS_vendor_id_3GPP,x,4,
 	 								AVP_DUPLICATE_DATA);
 	 AAAAddAVPToAVPList(&list,media_type);								

 		 								
 	
 	/*Max-Requested-Bandwidth-UL*/
 	/*Max-Requested-Bandwidth-DL*/
 	/*SDP bodies have been check by gq_create_add_media_subcomponents*/
 	
 	i=1;
 	ptr=find_sdp_line(sdp200.s,(sdp200.s+sdp200.len),'m');
 	
 	while(i!=number) 
 	{
 		ptr=find_next_sdp_line(ptr,(sdp200.s+sdp200.len),'m',NULL);
 		i++;	
 	}
 	
 	
 	
 	if(tag==1)
 	{
 		/*in the invite its defined how much bandwidth
 		 * you want in the downlink!*/
 		extract_bandwidth(&bwDL,sdpinvite,mline);
 		extract_bandwidth(&bwUL,sdp200,ptr);
 	} else {
 		extract_bandwidth(&bwDL,sdp200,ptr);
 		extract_bandwidth(&bwUL,sdpinvite,mline);	
 		 		
 	}
 	/*
 	 * IN a SDP b=AS:x line  the x is the amount of bandwidth
 	 * the sender of the SDP body is willing to RECEIVE 
 	 * therefor the next code is right 
 	 * 
 	 * */
	if (bwDL.bAS!=0)
	 {
	 	
 			set_4bytes(x,bwDL.bAS);
 			Max_UL=cdpb.AAACreateAVP(AVP_IMS_Max_Requested_Bandwidth_UL,
											AAA_AVP_FLAG_MANDATORY|AAA_AVP_FLAG_VENDOR_SPECIFIC,
											IMS_vendor_id_3GPP,x,4,
											AVP_DUPLICATE_DATA);
			AAAAddAVPToAVPList(&list,Max_UL);
		
	 }
	if (bwUL.bAS!=0)
	{
 			set_4bytes(x,bwUL.bAS);
 			Max_DL=cdpb.AAACreateAVP(AVP_IMS_Max_Requested_Bandwidth_DL,
											AAA_AVP_FLAG_MANDATORY|AAA_AVP_FLAG_VENDOR_SPECIFIC,
											IMS_vendor_id_3GPP,x,4,
											AVP_DUPLICATE_DATA);
			AAAAddAVPToAVPList(&list,Max_DL);
			
	}
	
	
	
 	/*Flow-Status*/
 	/*lets follow the specs*/
 		if (tag==0)
 		{
 			extract_token(mline,port,Gq_MAX_Char,2);
 		} else {
 			extract_token(ptr,port,Gq_MAX_Char,2);
 		}
 		if(strncmp(port,"0",1)==0)
 		{
 			set_4bytes(x,AVP_IMS_Flow_Status_Removed);
  		} else {
  			
  			if (tag==1)
  			{
  				a=check_atributes(sdp200,ptr);
  			} else {
  				a=check_atributes(sdpinvite,mline);
  			}
  			
  			if (a==1)
  			{
  				set_4bytes(x,AVP_IMS_Flow_Status_Enabled_Uplink);
  			} else if(a==2)
  			{
  				set_4bytes(x,AVP_IMS_Flow_Status_Enabled_Downlink);
  			} else {
  				set_4bytes(x,AVP_IMS_Flow_Status_Enabled);
  			} 
  			
  			
 		}
 	
 	
 		
 		flow_status=cdpb.AAACreateAVP(AVP_IMS_Flow_Status,
 											AAA_AVP_FLAG_MANDATORY|AAA_AVP_FLAG_VENDOR_SPECIFIC,
 											IMS_vendor_id_3GPP,x,4,
 											AVP_DUPLICATE_DATA);
		AAAAddAVPToAVPList(&list,flow_status);
 	
 	
 	/*RR and RS*/
 	
 	
 	x[0]=0; x[1]=0; x[2]=0; x[3]=0;
 	
		
			if(bwUL.bRR!=0) {
				set_4bytes(x,bwUL.bRR);
			} /*else if (bwDL.bRS!=0) {
				set_4bytes(x,bwDL.bRS);
			}*/
		
	RR=0;
	if (x[0]!=0 || x[1]!=0 || x[2]!=0 || x[3]!=0) {
			RR=cdpb.AAACreateAVP(AVP_IMS_RR_Bandwidth,
											AAA_AVP_FLAG_MANDATORY|AAA_AVP_FLAG_VENDOR_SPECIFIC,
											IMS_vendor_id_3GPP,x,4,
											AVP_DUPLICATE_DATA);
			AAAAddAVPToAVPList(&list,RR);
			 	 		
	}	
	

 	x[0]=0; x[1]=0; x[2]=0; x[3]=0;
 	
			if(bwUL.bRS!=0) 
			{
				set_4bytes(x,bwUL.bRS);
			} /*else if(bwDL.bRR!=0){
				set_4bytes(x,bwDL.bRR);
			}*/
	
			
 	RS=0;
	if (x[0]!=0 || x[1]!=0 || x[2]!=0 || x[3]!=0)
	 {
		RS=cdpb.AAACreateAVP(AVP_IMS_RS_Bandwidth,
								AAA_AVP_FLAG_MANDATORY|AAA_AVP_FLAG_VENDOR_SPECIFIC,
								IMS_vendor_id_3GPP,x,4,
								AVP_DUPLICATE_DATA);
		AAAAddAVPToAVPList(&list,RS);
		
	}		
 	
 	
 	
 	
 	
 	
 	/*codec-data*/
 	 	
 	
 	if (tag==0)
 	{
 		/*0 means uplink offer*/
 		codec_data1=Gq_create_codec_data(sdpinvite,number,0);
 		AAAAddAVPToAVPList(&list,codec_data1);
 		/*3 means downlink answer*/
 		codec_data2=Gq_create_codec_data(sdp200,number,3);
 		AAAAddAVPToAVPList(&list,codec_data2);
 	} else { 
 		/*2 means downlink offer*/
 		codec_data1=Gq_create_codec_data(sdpinvite,number,2);
 		AAAAddAVPToAVPList(&list,codec_data1);
 		/*1 means uplink answer*/
 		codec_data2=Gq_create_codec_data(sdp200,number,1);
 		AAAAddAVPToAVPList(&list,codec_data2);
 	
 	}
 	/*now group them in one big AVP and free them*/
 	
 	data=cdpb.AAAGroupAVPS(list);
  	 		
  	Gq_add_avp(msg,data.s,data.len,AVP_IMS_Media_Component_Description,
 				AAA_AVP_FLAG_MANDATORY|AAA_AVP_FLAG_VENDOR_SPECIFIC,
 				IMS_vendor_id_3GPP,
 				AVP_DUPLICATE_DATA,
 				__FUNCTION__);
 	
 			
 	cdpb.AAAFreeAVP(&media_component_number);
 	for(i=0;i<n;i++)
 	{
 		cdpb.AAAFreeAVP(&media_sub_component[i]);
 	}
 	
 	if (bwUL.bAS!=0)
	 {	
	 	cdpb.AAAFreeAVP(&Max_UL);	 	
	 }
	if (bwDL.bAS!=0)
	{
		cdpb.AAAFreeAVP(&Max_DL);		
	}
	
	
	cdpb.AAAFreeAVP(&flow_status);
	if (RS!=0)
 	{
 		cdpb.AAAFreeAVP(&RS);
 	}
 	if (RR!=0)
 	{
 		cdpb.AAAFreeAVP(&RR);
 	}
 	
 	cdpb.AAAFreeAVP(&media_type);
 	cdpb.AAAFreeAVP(&codec_data1);
 	cdpb.AAAFreeAVP(&codec_data2);
 	
 	list.tail=0;
 	list.head=0;
 	return 1;
 }
Esempio n. 9
0
/*
 * Converts a PEM encoded file into its binary form
 *
 * RFC 1421 Privacy Enhancement for Electronic Mail, February 1993
 * RFC 934 Message Encapsulation, January 1985
 *
 * We no longer support decrypting PEM files - those can only come in via NSS
 */
err_t pemtobin(chunk_t *blob)
{
	typedef enum {
		PEM_PRE    = 0,
		PEM_MSG    = 1,
		PEM_HEADER = 2,
		PEM_BODY   = 3,
		PEM_POST   = 4,
		PEM_ABORT  = 5
	} state_t;

	state_t state  = PEM_PRE;

	chunk_t src    = *blob;
	chunk_t dst    = *blob;
	chunk_t line   = empty_chunk;

	/* zero size of converted blob */
	dst.len = 0;

	while (fetchline(&src, &line)) {
		if (state == PEM_PRE) {
			if (find_boundary("BEGIN", &line)) {
				state = PEM_MSG;
			}
			continue;
		} else {
			if (find_boundary("END", &line)) {
				state = PEM_POST;
				break;
			}
			if (state == PEM_MSG) {
				state = (memchr(line.ptr, ':',
						line.len) == NULL) ?
					PEM_BODY : PEM_HEADER;
			}
			if (state == PEM_HEADER) {
				chunk_t name  = empty_chunk;
				chunk_t value = empty_chunk;

				/* an empty line separates HEADER and BODY */
				if (line.len == 0) {
					state = PEM_BODY;
					continue;
				}

				/* we are looking for a name: value pair */
				if (!extract_parameter(&name, &value, &line))
					continue;

				if (match("Proc-Type",
						&name) && *value.ptr == '4')
					return "Proc-Type: encrypted files no longer supported outside of the NSS database, please import these into NSS";

				else if (match("DEK-Info", &name))
					return "DEK-Info: encrypted files no longer supported outside of the NSS database, please import these into NSS";

			} else {
				/* state is PEM_BODY */
				const char *ugh = NULL;
				size_t len = 0;
				chunk_t data;

				/* remove any trailing whitespace */
				if (!extract_token(&data, ' ', &line))
					data = line;

				ugh = ttodata((char *)data.ptr, data.len, 64,
					(char *)dst.ptr,
					blob->len - dst.len, &len);
				if (ugh) {
					DBG(DBG_PARSING,
						DBG_log("  %s", ugh));
					state = PEM_ABORT;
					break;
				} else {
					dst.ptr += len;
					dst.len += len;
				}
			}
		}
	}
	/* set length to size of binary blob */
	blob->len = dst.len;

	if (state != PEM_POST)
		return "file coded in unknown format, discarded";

	return NULL;
}
Esempio n. 10
0
static int parse_attribute_crypto(struct sdp_attribute *output) {
	PARSE_DECL;
	char *endp;
	struct attribute_crypto *c;
	int salt_key_len, enc_salt_key_len;
	int b64_state = 0;
	unsigned int b64_save = 0;
	gsize ret;
	str s;
	u_int32_t u32;
	const char *err;

	output->attr = ATTR_CRYPTO;

	PARSE_INIT;
	EXTRACT_TOKEN(u.crypto.tag_str);
	EXTRACT_TOKEN(u.crypto.crypto_suite_str);
	EXTRACT_TOKEN(u.crypto.key_params_str);

	c = &output->u.crypto;

	c->tag = strtoul(c->tag_str.s, &endp, 10);
	err = "invalid 'tag'";
	if (endp == c->tag_str.s)
		goto error;

	c->crypto_suite = crypto_find_suite(&c->crypto_suite_str);
	err = "unknown crypto suite";
	if (!c->crypto_suite)
		goto error;
	salt_key_len = c->crypto_suite->master_key_len
			+ c->crypto_suite->master_salt_len;
	enc_salt_key_len = ceil((double) salt_key_len * 4.0/3.0);

	err = "invalid key parameter length";
	if (c->key_params_str.len < 7 + enc_salt_key_len)
		goto error;
	err = "unknown key method";
	if (strncasecmp(c->key_params_str.s, "inline:", 7))
		goto error;
	c->key_base64_str = c->key_params_str;
	str_shift(&c->key_base64_str, 7);
	ret = g_base64_decode_step(c->key_base64_str.s, enc_salt_key_len,
			(guchar *) c->key_salt_buf, &b64_state, &b64_save);
	err = "invalid base64 encoding";
	if (ret != salt_key_len)
		goto error;

	c->master_key.s = c->key_salt_buf;
	c->master_key.len = c->crypto_suite->master_key_len;
	c->salt.s = c->master_key.s + c->master_key.len;
	c->salt.len = c->crypto_suite->master_salt_len;

	c->lifetime_str = c->key_params_str;
	str_shift(&c->lifetime_str, 7 + enc_salt_key_len);
	if (c->lifetime_str.len >= 2) {
		err = "invalid key parameter syntax";
		if (c->lifetime_str.s[0] != '|')
			goto error;
		str_shift(&c->lifetime_str, 1);
		str_chr_str(&c->mki_str, &c->lifetime_str, '|');
		if (!c->mki_str.s) {
			if (str_chr(&c->lifetime_str, ':')) {
				c->mki_str = c->lifetime_str;
				c->lifetime_str = STR_NULL;
			}
		}
		else {
			c->lifetime_str.len = c->mki_str.s - c->lifetime_str.s;
			str_shift(&c->mki_str, 1);
		}
	}
	else
		c->lifetime_str = STR_NULL;

	if (c->lifetime_str.s) {
		if (c->lifetime_str.len >= 3 && !memcmp(c->lifetime_str.s, "2^", 2)) {
			c->lifetime = strtoull(c->lifetime_str.s + 2, NULL, 10);
			err = "invalid key lifetime";
			if (!c->lifetime || c->lifetime > 64)
				goto error;
			c->lifetime = 1ULL << c->lifetime;
		}
		else
			c->lifetime = strtoull(c->lifetime_str.s, NULL, 10);

		err = "invalid key lifetime";
		if (!c->lifetime || c->lifetime > c->crypto_suite->srtp_lifetime
#ifdef STRICT_SDES_KEY_LIFETIME
				|| c->lifetime > c->crypto_suite->srtcp_lifetime
#endif
				)
			goto error;
	}

	if (c->mki_str.s) {
		str_chr_str(&s, &c->mki_str, ':');
		err = "invalid MKI specification";
		if (!s.s)
			goto error;
		u32 = htonl(strtoul(c->mki_str.s, NULL, 10));
		c->mki_len = strtoul(s.s + 1, NULL, 10);
		err = "MKI too long";
		if (c->mki_len > sizeof(c->mki))
			goto error;
		memset(c->mki, 0, c->mki_len);
		if (sizeof(u32) >= c->mki_len)
			memcpy(c->mki, ((void *) &u32) + (sizeof(u32) - c->mki_len), c->mki_len);
		else
			memcpy(c->mki + (c->mki_len - sizeof(u32)), &u32, sizeof(u32));
	}

	while (extract_token(&start, end, &s) == 0) {
		if (!str_cmp(&s, "UNENCRYPTED_SRTCP"))
			c->unencrypted_srtcp = 1;
		else if (!str_cmp(&s, "UNENCRYPTED_SRTP"))
			c->unencrypted_srtp = 1;
		else if (!str_cmp(&s, "UNAUTHENTICATED_SRTP"))
			c->unauthenticated_srtp = 1;
	}

	return 0;

error:
	ilog(LOG_ERROR, "Failed to parse a=crypto attribute: %s", err);
	return -1;
}
Esempio n. 11
0
/**
 * Converts a PEM encoded file into its binary form (RFC 1421, RFC 934)
 */
static status_t pem_to_bin(chunk_t *blob, bool *pgp)
{
	typedef enum {
		PEM_PRE    = 0,
		PEM_MSG    = 1,
		PEM_HEADER = 2,
		PEM_BODY   = 3,
		PEM_POST   = 4,
		PEM_ABORT  = 5
	} state_t;

	encryption_algorithm_t alg = ENCR_UNDEFINED;
	size_t key_size = 0;
	bool encrypted = FALSE;
	state_t state  = PEM_PRE;
	chunk_t src    = *blob;
	chunk_t dst    = *blob;
	chunk_t line   = chunk_empty;
	chunk_t iv     = chunk_empty;
	u_char iv_buf[HASH_SIZE_MD5];
	status_t status = NOT_FOUND;
	enumerator_t *enumerator;
	shared_key_t *shared;

	dst.len = 0;
	iv.ptr = iv_buf;
	iv.len = 0;

	while (fetchline(&src, &line))
	{
		if (state == PEM_PRE)
		{
			if (find_boundary("BEGIN", &line))
			{
				state = PEM_MSG;
			}
			continue;
		}
		else
		{
			if (find_boundary("END", &line))
			{
				state = PEM_POST;
				break;
			}
			if (state == PEM_MSG)
			{
				state = PEM_HEADER;
				if (memchr(line.ptr, ':', line.len) == NULL)
				{
					state = PEM_BODY;
				}
			}
			if (state == PEM_HEADER)
			{
				err_t ugh = NULL;
				chunk_t name  = chunk_empty;
				chunk_t value = chunk_empty;

				/* an empty line separates HEADER and BODY */
				if (line.len == 0)
				{
					state = PEM_BODY;
					continue;
				}

				/* we are looking for a parameter: value pair */
				DBG2(DBG_ASN, "  %.*s", (int)line.len, line.ptr);
				ugh = extract_parameter_value(&name, &value, &line);
				if (ugh != NULL)
				{
					continue;
				}
				if (match("Proc-Type", &name) && *value.ptr == '4')
				{
					encrypted = TRUE;
				}
				else if (match("DEK-Info", &name))
				{
					chunk_t dek;

					if (!extract_token(&dek, ',', &value))
					{
						dek = value;
					}
					if (match("DES-EDE3-CBC", &dek))
					{
						alg = ENCR_3DES;
						key_size = 24;
					}
					else if (match("AES-128-CBC", &dek))
					{
						alg = ENCR_AES_CBC;
						key_size = 16;
					}
					else if (match("AES-192-CBC", &dek))
					{
						alg = ENCR_AES_CBC;
						key_size = 24;
					}
					else if (match("AES-256-CBC", &dek))
					{
						alg = ENCR_AES_CBC;
						key_size = 32;
					}
					else
					{
						DBG1(DBG_ASN, "  encryption algorithm '%.*s'"
							 " not supported", (int)dek.len, dek.ptr);
						return NOT_SUPPORTED;
					}
					if (!eat_whitespace(&value) || value.len > 2*sizeof(iv_buf))
					{
						return PARSE_ERROR;
					}
					iv = chunk_from_hex(value, iv_buf);
				}
			}
			else /* state is PEM_BODY */
			{
				chunk_t data;

				/* remove any trailing whitespace */
				if (!extract_token(&data ,' ', &line))
				{
					data = line;
				}

				/* check for PGP armor checksum */
				if (*data.ptr == '=')
				{
					*pgp = TRUE;
					data.ptr++;
					data.len--;
					DBG2(DBG_ASN, "  armor checksum: %.*s", (int)data.len,
						 data.ptr);
					continue;
				}

				if (blob->len - dst.len < data.len / 4 * 3)
				{
					state = PEM_ABORT;
				}
				data = chunk_from_base64(data, dst.ptr);

				dst.ptr += data.len;
				dst.len += data.len;
			}
		}
	}
	/* set length to size of binary blob */
	blob->len = dst.len;

	if (state != PEM_POST)
	{
		DBG1(DBG_LIB, "  file coded in unknown format, discarded");
		return PARSE_ERROR;
	}
	if (!encrypted)
	{
		return SUCCESS;
	}

	enumerator = lib->credmgr->create_shared_enumerator(lib->credmgr,
											SHARED_PRIVATE_KEY_PASS, NULL, NULL);
	while (enumerator->enumerate(enumerator, &shared, NULL, NULL))
	{
		chunk_t passphrase, chunk;

		passphrase = shared->get_key(shared);
		chunk = chunk_clone(*blob);
		status = pem_decrypt(&chunk, alg, key_size, iv, passphrase);
		if (status == SUCCESS)
		{
			memcpy(blob->ptr, chunk.ptr, chunk.len);
			blob->len = chunk.len;
		}
		free(chunk.ptr);
		if (status != INVALID_ARG)
		{	/* try again only if passphrase invalid */
			break;
		}
	}
	enumerator->destroy(enumerator);
	return status;
}
Esempio n. 12
0
/*
 * create a new room
 */
void cmd_cre8(char *args)
{
	int cre8_ok;
	char new_room_name[ROOMNAMELEN];
	int new_room_type;
	char new_room_pass[32];
	int new_room_floor;
	int new_room_view;
	char *notification_message = NULL;
	unsigned newflags;
	struct floor *fl;
	int avoid_access = 0;

	cre8_ok = extract_int(args, 0);
	extract_token(new_room_name, args, 1, '|', sizeof new_room_name);
	new_room_name[ROOMNAMELEN - 1] = 0;
	new_room_type = extract_int(args, 2);
	extract_token(new_room_pass, args, 3, '|', sizeof new_room_pass);
	avoid_access = extract_int(args, 5);
	new_room_view = extract_int(args, 6);
	new_room_pass[9] = 0;
	new_room_floor = 0;

	if ((IsEmptyStr(new_room_name)) && (cre8_ok == 1)) {
		cprintf("%d Invalid room name.\n", ERROR + ILLEGAL_VALUE);
		return;
	}

	if (!strcasecmp(new_room_name, MAILROOM)) {
		cprintf("%d '%s' already exists.\n",
			ERROR + ALREADY_EXISTS, new_room_name);
		return;
	}

	if (num_parms(args) >= 5) {
		fl = CtdlGetCachedFloor(extract_int(args, 4));
		if (fl == NULL) {
			cprintf("%d Invalid floor number.\n",
				ERROR + INVALID_FLOOR_OPERATION);
			return;
		}
		else if ((fl->f_flags & F_INUSE) == 0) {
			cprintf("%d Invalid floor number.\n",
				ERROR + INVALID_FLOOR_OPERATION);
			return;
		} else {
			new_room_floor = extract_int(args, 4);
		}
	}

	if (CtdlAccessCheck(ac_logged_in)) return;

	if (CC->user.axlevel < CtdlGetConfigInt("c_createax") && !CC->internal_pgm) {
		cprintf("%d You need higher access to create rooms.\n",
			ERROR + HIGHER_ACCESS_REQUIRED);
		return;
	}

	if ((IsEmptyStr(new_room_name)) && (cre8_ok == 0)) {
		cprintf("%d Ok to create rooms.\n", CIT_OK);
		return;
	}

	if ((new_room_type < 0) || (new_room_type > 5)) {
		cprintf("%d Invalid room type.\n", ERROR + ILLEGAL_VALUE);
		return;
	}

	if (new_room_type == 5) {
		if (CC->user.axlevel < AxAideU) {
			cprintf("%d Higher access required\n", 
				ERROR + HIGHER_ACCESS_REQUIRED);
			return;
		}
	}

	/* Check to make sure the requested room name doesn't already exist */
	newflags = CtdlCreateRoom(new_room_name,
				new_room_type, new_room_pass, new_room_floor,
				0, avoid_access, new_room_view);
	if (newflags == 0) {
		cprintf("%d '%s' already exists.\n",
			ERROR + ALREADY_EXISTS, new_room_name);
		return;
	}

	if (cre8_ok == 0) {
		cprintf("%d OK to create '%s'\n", CIT_OK, new_room_name);
		return;
	}

	/* If we reach this point, the room needs to be created. */

	newflags = CtdlCreateRoom(new_room_name,
			   new_room_type, new_room_pass, new_room_floor, 1, 0,
			   new_room_view);

	/* post a message in Aide> describing the new room */
	notification_message = malloc(1024);
	snprintf(notification_message, 1024,
		"A new room called \"%s\" has been created by %s%s%s%s%s%s\n",
		new_room_name,
		(CC->logged_in ? CC->curr_user : "******"),
		((newflags & QR_MAILBOX) ? " [personal]" : ""),
		((newflags & QR_PRIVATE) ? " [private]" : ""),
		((newflags & QR_GUESSNAME) ? " [hidden]" : ""),
		((newflags & QR_PASSWORDED) ? " Password: "******""),
		((newflags & QR_PASSWORDED) ? new_room_pass : "")
	);
	CtdlAideMessage(notification_message, "Room Creation Message");
	free(notification_message);

	cprintf("%d '%s' has been created.\n", CIT_OK, new_room_name);
}
Esempio n. 13
0
/**
 * Converts a PEM encoded file into its binary form (RFC 1421, RFC 934)
 */
static status_t pem_to_bin(chunk_t *blob, chunk_t(*cb)(void*,int), void *cb_data,
						   bool *pgp)
{
	typedef enum {
		PEM_PRE    = 0,
		PEM_MSG    = 1,
		PEM_HEADER = 2,
		PEM_BODY   = 3,
		PEM_POST   = 4,
		PEM_ABORT  = 5
	} state_t;

	encryption_algorithm_t alg = ENCR_UNDEFINED;
	size_t key_size = 0;
	bool encrypted = FALSE;
	state_t state  = PEM_PRE;
	chunk_t src    = *blob;
	chunk_t dst    = *blob;
	chunk_t line   = chunk_empty;
	chunk_t iv     = chunk_empty;
	chunk_t passphrase;
	int try = 0;
	u_char iv_buf[HASH_SIZE_MD5];

	dst.len = 0;
	iv.ptr = iv_buf;
	iv.len = 0;

	while (fetchline(&src, &line))
	{
		if (state == PEM_PRE)
		{
			if (find_boundary("BEGIN", &line))
			{
				state = PEM_MSG;
			}
			continue;
		}
		else
		{
			if (find_boundary("END", &line))
			{
				state = PEM_POST;
				break;
			}
			if (state == PEM_MSG)
			{
				state = PEM_HEADER;
				if (memchr(line.ptr, ':', line.len) == NULL)
				{
					state = PEM_BODY;
				}
			}
			if (state == PEM_HEADER)
			{
				err_t ugh = NULL;
				chunk_t name  = chunk_empty;
				chunk_t value = chunk_empty;

				/* an empty line separates HEADER and BODY */
				if (line.len == 0)
				{
					state = PEM_BODY;
					continue;
				}

				/* we are looking for a parameter: value pair */
				DBG2(DBG_LIB, "  %.*s", (int)line.len, line.ptr);
				ugh = extract_parameter_value(&name, &value, &line);
				if (ugh != NULL)
				{
					continue;
				}
				if (match("Proc-Type", &name) && *value.ptr == '4')
				{
					encrypted = TRUE;
				}
				else if (match("DEK-Info", &name))
				{
					chunk_t dek;

					if (!extract_token(&dek, ',', &value))
					{
						dek = value;
					}
					if (match("DES-EDE3-CBC", &dek))
					{
						alg = ENCR_3DES;
						key_size = 24;
					}
					else if (match("AES-128-CBC", &dek))
					{
						alg = ENCR_AES_CBC;
						key_size = 16;
					}
					else if (match("AES-192-CBC", &dek))
					{
						alg = ENCR_AES_CBC;
						key_size = 24;
					}
					else if (match("AES-256-CBC", &dek))
					{
						alg = ENCR_AES_CBC;
						key_size = 32;
					}
					else
					{
						DBG1(DBG_LIB, "  encryption algorithm '%.*s'"
							 " not supported", dek.len, dek.ptr);
						return NOT_SUPPORTED;
					}
					eat_whitespace(&value);
					iv = chunk_from_hex(value, iv.ptr);
				}
			}
			else /* state is PEM_BODY */
			{
				chunk_t data;

				/* remove any trailing whitespace */
				if (!extract_token(&data ,' ', &line))
				{
					data = line;
				}

				/* check for PGP armor checksum */
				if (*data.ptr == '=')
				{
					*pgp = TRUE;
					data.ptr++;
					data.len--;
					DBG2(DBG_LIB, "  armor checksum: %.*s", (int)data.len,
						 data.ptr);
					continue;
				}

				if (blob->len - dst.len < data.len / 4 * 3)
				{
					state = PEM_ABORT;
				}
				data = chunk_from_base64(data, dst.ptr);

				dst.ptr += data.len;
				dst.len += data.len;
			}
		}
	}
	/* set length to size of binary blob */
	blob->len = dst.len;

	if (state != PEM_POST)
	{
		DBG1(DBG_LIB, "  file coded in unknown format, discarded");
		return PARSE_ERROR;
	}
	if (!encrypted)
	{
		return SUCCESS;
	}
	if (!cb)
	{
		DBG1(DBG_LIB, "  missing passphrase");
		return INVALID_ARG;
	}
	while (TRUE)
	{
		passphrase = cb(cb_data, ++try);
		if (!passphrase.len || !passphrase.ptr)
		{
			return INVALID_ARG;
		}
		switch (pem_decrypt(blob, alg, key_size, iv, passphrase))
		{
			case INVALID_ARG:
				/* bad passphrase, retry */
				continue;
			case SUCCESS:
				return SUCCESS;
			default:
				return FAILED;
		}
	}
}
Esempio n. 14
0
/*
 * set room parameters (admin or room admin command)
 */
void cmd_setr(char *args)
{
	char buf[256];
	int new_order = 0;
	int r;
	int new_floor;
	char new_name[ROOMNAMELEN];

	if (CtdlAccessCheck(ac_logged_in)) return;

	if (num_parms(args) >= 6) {
		new_floor = extract_int(args, 5);
	} else {
		new_floor = (-1);	/* don't change the floor */
	}

	/* When is a new name more than just a new name?  When the old name
	 * has a namespace prefix.
	 */
	if (CC->room.QRflags & QR_MAILBOX) {
		sprintf(new_name, "%010ld.", atol(CC->room.QRname) );
	} else {
		safestrncpy(new_name, "", sizeof new_name);
	}
	extract_token(&new_name[strlen(new_name)], args, 0, '|', (sizeof new_name - strlen(new_name)));

	r = CtdlRenameRoom(CC->room.QRname, new_name, new_floor);

	if (r == crr_room_not_found) {
		cprintf("%d Internal error - room not found?\n", ERROR + INTERNAL_ERROR);
	} else if (r == crr_already_exists) {
		cprintf("%d '%s' already exists.\n",
			ERROR + ALREADY_EXISTS, new_name);
	} else if (r == crr_noneditable) {
		cprintf("%d Cannot edit this room.\n", ERROR + NOT_HERE);
	} else if (r == crr_invalid_floor) {
		cprintf("%d Target floor does not exist.\n",
			ERROR + INVALID_FLOOR_OPERATION);
	} else if (r == crr_access_denied) {
		cprintf("%d You do not have permission to edit '%s'\n",
			ERROR + HIGHER_ACCESS_REQUIRED,
			CC->room.QRname);
	} else if (r != crr_ok) {
		cprintf("%d Error: CtdlRenameRoom() returned %d\n",
			ERROR + INTERNAL_ERROR, r);
	}

	if (r != crr_ok) {
		return;
	}

	CtdlGetRoom(&CC->room, new_name);

	/* Now we have to do a bunch of other stuff */

	if (num_parms(args) >= 7) {
		new_order = extract_int(args, 6);
		if (new_order < 1)
			new_order = 1;
		if (new_order > 127)
			new_order = 127;
	}

	CtdlGetRoomLock(&CC->room, CC->room.QRname);

	/* Directory room */
	extract_token(buf, args, 2, '|', sizeof buf);
	buf[15] = 0;
	safestrncpy(CC->room.QRdirname, buf,
		sizeof CC->room.QRdirname);

	/* Default view */
	if (num_parms(args) >= 8) {
		CC->room.QRdefaultview = extract_int(args, 7);
	}

	/* Second set of flags */
	if (num_parms(args) >= 9) {
		CC->room.QRflags2 = extract_int(args, 8);
	}

	/* Misc. flags */
	CC->room.QRflags = (extract_int(args, 3) | QR_INUSE);
	/* Clean up a client boo-boo: if the client set the room to
	 * guess-name or passworded, ensure that the private flag is
	 * also set.
	 */
	if ((CC->room.QRflags & QR_GUESSNAME)
	    || (CC->room.QRflags & QR_PASSWORDED))
		CC->room.QRflags |= QR_PRIVATE;

	/* Some changes can't apply to BASEROOM */
	if (!strncasecmp(CC->room.QRname, CtdlGetConfigStr("c_baseroom"), ROOMNAMELEN)) {
		CC->room.QRorder = 0;
		CC->room.QRpasswd[0] = '\0';
		CC->room.QRflags &= ~(QR_PRIVATE & QR_PASSWORDED &
			QR_GUESSNAME & QR_PREFONLY & QR_MAILBOX);
		CC->room.QRflags |= QR_PERMANENT;
	} else {	
		/* March order (doesn't apply to AIDEROOM) */
		if (num_parms(args) >= 7)
			CC->room.QRorder = (char) new_order;
		/* Room password */
		extract_token(buf, args, 1, '|', sizeof buf);
		buf[10] = 0;
		safestrncpy(CC->room.QRpasswd, buf,
			    sizeof CC->room.QRpasswd);
		/* Kick everyone out if the client requested it
		 * (by changing the room's generation number)
		 */
		if (extract_int(args, 4)) {
			time(&CC->room.QRgen);
		}
	}
	/* Some changes can't apply to AIDEROOM */
	if (!strncasecmp(CC->room.QRname, CtdlGetConfigStr("c_baseroom"), ROOMNAMELEN)) {
		CC->room.QRorder = 0;
		CC->room.QRflags &= ~QR_MAILBOX;
		CC->room.QRflags |= QR_PERMANENT;
	}

	/* Write the room record back to disk */
	CtdlPutRoomLock(&CC->room);

	/* Create a room directory if necessary */
	if (CC->room.QRflags & QR_DIRECTORY) {
		snprintf(buf, sizeof buf,"%s/%s",
				 ctdl_file_dir,
				 CC->room.QRdirname);
		mkdir(buf, 0755);
	}
	snprintf(buf, sizeof buf, "The room \"%s\" has been edited by %s.\n",
		CC->room.QRname,
		(CC->logged_in ? CC->curr_user : "******")
	);
	CtdlAideMessage(buf, "Room modification Message");
	cprintf("%d Ok\n", CIT_OK);
}
Esempio n. 15
0
/*
 * RDIR command for room directory
 */
void cmd_rdir(char *cmdbuf)
{
	char buf[256];
	char comment[256];
	FILE *fd;
	struct stat statbuf;
	DIR *filedir = NULL;
	struct dirent *filedir_entry;
	int d_namelen;
	char buf2[SIZ];
	char mimebuf[64];
	long len;
	
	if (CtdlAccessCheck(ac_logged_in)) return;
	
	CtdlGetRoom(&CC->room, CC->room.QRname);
	CtdlGetUser(&CC->user, CC->curr_user);

	if ((CC->room.QRflags & QR_DIRECTORY) == 0) {
		cprintf("%d not here.\n", ERROR + NOT_HERE);
		return;
	}
	if (((CC->room.QRflags & QR_VISDIR) == 0)
	    && (CC->user.axlevel < AxAideU)
	    && (CC->user.usernum != CC->room.QRroomaide)) {
		cprintf("%d not here.\n", ERROR + HIGHER_ACCESS_REQUIRED);
		return;
	}

	snprintf(buf, sizeof buf, "%s/%s", ctdl_file_dir, CC->room.QRdirname);
	filedir = opendir (buf);
	
	if (filedir == NULL) {
		cprintf("%d not here.\n", ERROR + HIGHER_ACCESS_REQUIRED);
		return;
	}
	cprintf("%d %s|%s/%s\n", LISTING_FOLLOWS, CtdlGetConfigStr("c_fqdn"), ctdl_file_dir, CC->room.QRdirname);
	
	snprintf(buf, sizeof buf, "%s/%s/filedir", ctdl_file_dir, CC->room.QRdirname);
	fd = fopen(buf, "r");
	if (fd == NULL)
		fd = fopen("/dev/null", "r");
	while ((filedir_entry = readdir(filedir)))
	{
		if (strcasecmp(filedir_entry->d_name, "filedir") && filedir_entry->d_name[0] != '.')
		{
#ifdef _DIRENT_HAVE_D_NAMELEN
			d_namelen = filedir_entry->d_namlen;
#else
			d_namelen = strlen(filedir_entry->d_name);
#endif
			snprintf(buf, sizeof buf, "%s/%s/%s", ctdl_file_dir, CC->room.QRdirname, filedir_entry->d_name);
			stat(buf, &statbuf);	/* stat the file */
			if (!(statbuf.st_mode & S_IFREG))
			{
				snprintf(buf2, sizeof buf2,
					"\"%s\" appears in the file directory for room \"%s\" but is not a regular file.  Directories, named pipes, sockets, etc. are not usable in Citadel room directories.\n",
					buf, CC->room.QRname
				);
				CtdlAideMessage(buf2, "Unusable data found in room directory");
				continue;	/* not a useable file type so don't show it */
			}
			safestrncpy(comment, "", sizeof comment);
			fseek(fd, 0L, 0);	/* rewind descriptions file */
			/* Get the description from the descriptions file */
			while ((fgets(buf, sizeof buf, fd) != NULL) && (IsEmptyStr(comment))) 
			{
				buf[strlen(buf) - 1] = 0;
				if ((!strncasecmp(buf, filedir_entry->d_name, d_namelen)) && (buf[d_namelen] == ' '))
					safestrncpy(comment, &buf[d_namelen + 1], sizeof comment);
			}
			len = extract_token (mimebuf, comment, 0,' ', 64);
			if ((len <0) || strchr(mimebuf, '/') == NULL)
			{
				snprintf (mimebuf, 64, "application/octetstream");
				len = 0;
			}
			cprintf("%s|%ld|%s|%s\n", 
				filedir_entry->d_name, 
				(long)statbuf.st_size, 
				mimebuf, 
				&comment[len]);
		}
	}
	fclose(fd);
	closedir(filedir);
	
	cprintf("000\n");
}
Esempio n. 16
0
/* 
 * cmd_goto()  -  goto a new room
 */
void cmd_goto(char *gargs)
{
	struct ctdlroom QRscratch;
	int c;
	int ok = 0;
	int ra;
	char augmented_roomname[ROOMNAMELEN];
	char towhere[ROOMNAMELEN];
	char password[32];
	int transiently = 0;

	if (CtdlAccessCheck(ac_logged_in_or_guest)) return;

	extract_token(towhere, gargs, 0, '|', sizeof towhere);
	extract_token(password, gargs, 1, '|', sizeof password);
	transiently = extract_int(gargs, 2);

	CtdlGetUser(&CC->user, CC->curr_user);

	/*
	 * Handle some of the macro named rooms
	 */
	convert_room_name_macros(towhere, sizeof towhere);

	/* First try a regular match */
	c = CtdlGetRoom(&QRscratch, towhere);

	/* Then try a mailbox name match */
	if (c != 0) {
		CtdlMailboxName(augmented_roomname, sizeof augmented_roomname,
			    &CC->user, towhere);
		c = CtdlGetRoom(&QRscratch, augmented_roomname);
		if (c == 0)
			safestrncpy(towhere, augmented_roomname, sizeof towhere);
	}

	/* And if the room was found... */
	if (c == 0) {

		/* Let internal programs go directly to any room. */
		if (CC->internal_pgm) {
			memcpy(&CC->room, &QRscratch,
				sizeof(struct ctdlroom));
			CtdlUserGoto(NULL, 1, transiently, NULL, NULL, NULL, NULL);
			return;
		}

		/* See if there is an existing user/room relationship */
		CtdlRoomAccess(&QRscratch, &CC->user, &ra, NULL);

		/* normal clients have to pass through security */
		if (ra & UA_GOTOALLOWED) {
			ok = 1;
		}

		if (ok == 1) {
			if ((QRscratch.QRflags & QR_MAILBOX) &&
			    ((ra & UA_GOTOALLOWED))) {
				memcpy(&CC->room, &QRscratch,
					sizeof(struct ctdlroom));
				CtdlUserGoto(NULL, 1, transiently, NULL, NULL, NULL, NULL);
				return;
			} else if ((QRscratch.QRflags & QR_PASSWORDED) &&
			    ((ra & UA_KNOWN) == 0) &&
			    (strcasecmp(QRscratch.QRpasswd, password)) &&
			    (CC->user.axlevel < AxAideU)
			    ) {
				cprintf("%d wrong or missing passwd\n",
					ERROR + PASSWORD_REQUIRED);
				return;
			} else if ((QRscratch.QRflags & QR_PRIVATE) &&
				   ((QRscratch.QRflags & QR_PASSWORDED) == 0) &&
				   ((QRscratch.QRflags & QR_GUESSNAME) == 0) &&
				   ((ra & UA_KNOWN) == 0) &&
			           (CC->user.axlevel < AxAideU)
                                  ) {
				syslog(LOG_DEBUG, "Failed to acquire private room\n");
			} else {
				memcpy(&CC->room, &QRscratch,
					sizeof(struct ctdlroom));
				CtdlUserGoto(NULL, 1, transiently, NULL, NULL, NULL, NULL);
				return;
			}
		}
	}

	cprintf("%d room '%s' not found\n", ERROR + ROOM_NOT_FOUND, towhere);
}
Esempio n. 17
0
/**
 * Determine all TCP and UDP server sockets listening on physical interfaces
 */
static bool do_netstat(ietf_attr_port_filter_t *attr)
{
	FILE *file;
	char buf[BUF_LEN];
	chunk_t line, token;
	int n = 0;
	bool success = FALSE;
	const char system_v4[]   = "127.0.1.1";
	const char loopback_v4[] = "127.0.0.1";
	const char loopback_v6[] = "::1";

	/* Open a pipe stream for reading the output of the netstat commmand */
	file = popen("/bin/netstat -n -l -p -4 -6 --inet", "r");
	if (!file)
	{
		DBG1(DBG_IMC, "failed to run netstat command");
		return FALSE;
	}

	/* Read the output a line at a time */
	while (fgets(buf, sizeof(buf), file))
	{
		u_char *pos;
		u_int8_t new_protocol, protocol;
		u_int16_t new_port, port;
		int i;
		enumerator_t *enumerator;
		bool allowed, found = FALSE;

		DBG2(DBG_IMC, "%.*s", (int)(strlen(buf)-1), buf);

		if (n++ < 2)
		{
			/* skip the first two header lines */
			continue;
		}
		line = chunk_create(buf, strlen(buf));

		/* Extract the IP protocol type */
		if (!extract_token(&token, ' ', &line))
		{
			DBG1(DBG_IMC, "protocol field in netstat output not found");
			goto end;
		}
		if (match("tcp", &token) || match("tcp6", &token))
		{
			new_protocol = IPPROTO_TCP;
		}
		else if (match("udp", &token) || match("udp6", &token))
		{
			new_protocol = IPPROTO_UDP;
		}
		else
		{
			DBG1(DBG_IMC, "skipped unknown IP protocol in netstat output");
			continue;
		}

		/* Skip the Recv-Q and Send-Q fields */
		for (i = 0; i < 3; i++)
		{
			if (!eat_whitespace(&line) || !extract_token(&token, ' ', &line))
			{
				token = chunk_empty;
				break;
			}
		}
		if (token.len == 0)
		{
			DBG1(DBG_IMC, "local address field in netstat output not found");
			goto end;
		}

		/* Find the local port appended to the local address */
		pos = token.ptr + token.len;
		while (*--pos != ':' && --token.len);
		if (*pos != ':')
		{
			DBG1(DBG_IMC, "local port field in netstat output not found");
			goto end;
		}
		token.len--;

		/* ignore ports of IPv4 and IPv6 loopback interfaces
		   and the internal system IPv4 address */
		if ((token.len == strlen(system_v4) &&
				memeq(system_v4, token.ptr, token.len)) ||
			(token.len == strlen(loopback_v4) &&
				memeq(loopback_v4, token.ptr, token.len)) ||
			(token.len == strlen(loopback_v6) &&
				memeq(loopback_v6, token.ptr, token.len)))
		{
			continue;
		}

		/* convert the port string to an integer */
		new_port = atoi(pos+1);

		/* check if the there is already a port entry */
		enumerator = attr->create_port_enumerator(attr);
		while (enumerator->enumerate(enumerator, &allowed, &protocol, &port))
		{
			if (new_port == port && new_protocol == protocol)
			{
				found = TRUE;
			}
		}
		enumerator->destroy(enumerator);

		/* Skip the duplicate port entry */
		if (found)
		{
			continue;
		}

		/* Add new port entry */
		attr->add_port(attr, FALSE, new_protocol, new_port);
	}

	/* Successfully completed the parsing of the netstat output */
	success = TRUE;

end:
	/* Close the pipe stream */
	pclose(file);
	return success;
}
Esempio n. 18
0
int SLcmd_execute_string (char *str, SLcmd_Cmd_Table_Type *table)
{
   char *s, *arg_type, *last_str, *cmd_name;
   SLcmd_Cmd_Type *cmd;
   char *buf;
   int token_present;
   int i;
   int status;
   unsigned int len;
   int argc;
   unsigned int space;

   table->argc = 0;
   table->string_args = NULL;
   table->int_args = NULL;
   table->double_args = NULL;
   table->arg_type = NULL;

   buf = SLmake_string (str);
   if (buf == NULL)
     return -1;

   status = extract_token (&str, buf);
   if (status <= 0)
     {
	SLfree (buf);
	return status;
     }

   if (((len = strlen (buf)) >= 32)
       || (NULL == (cmd = SLcmd_find_command (buf, table->table))))
     {
	SLang_verror (SL_UNDEFINED_NAME,"%s: invalid command", buf);
	SLfree (buf);
	return -1;
     }

   if (NULL == (cmd_name = SLmake_string (buf)))
     {
	SLfree (buf);
	return -1;
     }

   space = 0;
   argc = 0;
   if (-1 == allocate_arg_space (table, argc, &space))
     {
	SLfree (buf);
	return -1;
     }
   table->arg_type[argc] = SLANG_STRING_TYPE;
   table->string_args[argc++] = cmd_name;

   arg_type = cmd->arg_type;
   status = -1;
   while (*arg_type)
     {
	int guess_type = 0;

	last_str = str;

	if (-1 == allocate_arg_space (table, argc, &space))
	  goto error;

	if (-1 == (token_present = extract_token (&str, buf)))
	  goto error;

	table->string_args[argc] = NULL;

	if (token_present)
	  {
	     char *b = buf;
	     len = strlen (b);

	     if ((*b == '"') && (len > 1))
	       {
		  b++;
		  len -= 2;
		  b[len] = 0;
		  guess_type = SLANG_STRING_TYPE;
		  SLexpand_escaped_string (buf, b, b + len);
		  len = strlen (buf);
	       }
	     else if ((*b == '\'') && (len > 1))
	       {
		  char ch;
		  b++;
		  len -= 2;
		  b[len] = 0;
		  guess_type = SLANG_INT_TYPE;
		  ch = *b;
		  if (ch == '\\')
		    (void) _SLexpand_escaped_char (b, &ch);
		  sprintf (buf, "%d", (unsigned char) ch);
		  len = strlen (buf);
	       }
	     else guess_type = SLang_guess_type (buf);
	  }

	switch (*arg_type++)
	  {
	     /* variable argument number */
	   case 'v':
	     if (token_present == 0) break;
	   case 'V':
	     if (token_present == 0)
	       {
		  SLang_verror (SL_INVALID_PARM, "%s: Expecting argument", cmd_name);
		  goto error;
	       }

	     while (*last_str == ' ') last_str++;
	     len = strlen (last_str);
	     str = last_str + len;

	     s = SLmake_nstring (last_str, len);
	     if (s == NULL) goto error;

	     table->arg_type[argc] = SLANG_STRING_TYPE;
	     table->string_args[argc++] = s;
	     break;

	   case 's':
	     if (token_present == 0) break;
	   case 'S':
	     if (token_present == 0)
	       {
		  SLang_verror (SL_TYPE_MISMATCH, "%s: Expecting string argument", cmd_name);
		  goto error;
	       }

	     s = SLmake_nstring (buf, len);
	     if (s == NULL) goto error;
	     table->arg_type[argc] = SLANG_STRING_TYPE;
	     table->string_args[argc++] = s;
	     break;

	     /* integer argument */
	   case 'i':
	     if (token_present == 0) break;
	   case 'I':
	     if ((token_present == 0) || (SLANG_INT_TYPE != guess_type))
	       {
		  SLang_verror (SL_TYPE_MISMATCH, "%s: Expecting integer argument", cmd_name);
		  goto error;
	       }

	     table->arg_type[argc] = SLANG_INT_TYPE;
	     table->int_args[argc++] = SLatoi((unsigned char *) buf);
	     break;

	     /* floating point arg */
#if SLANG_HAS_FLOAT
	   case 'f':
	     if (token_present == 0) break;
	   case 'F':
	     if ((token_present == 0) || (SLANG_STRING_TYPE == guess_type))
	       {
		  SLang_verror (SL_TYPE_MISMATCH, "%s: Expecting double argument", cmd_name);
		  goto error;
	       }
	     table->arg_type[argc] = SLANG_DOUBLE_TYPE;
	     table->double_args[argc++] = atof(buf);
	     break;
#endif
	     /* Generic type */
	   case 'g':
	     if (token_present == 0) break;
	   case 'G':
	     if (token_present == 0)
	       {
		  SLang_verror (SL_TYPE_MISMATCH, "%s: Expecting argument", cmd_name);
		  goto error;
	       }

	     switch (guess_type)
	       {
		case SLANG_INT_TYPE:
		  table->arg_type[argc] = SLANG_INT_TYPE;
		  table->int_args[argc++] = SLatoi((unsigned char *) buf);
		  break;

		case SLANG_STRING_TYPE:
		  s = SLmake_nstring (buf, len);
		  if (s == NULL) goto error;

		  table->arg_type[argc] = SLANG_STRING_TYPE;
		  table->string_args[argc++] = s;
		  break;
#if SLANG_HAS_FLOAT
		case SLANG_DOUBLE_TYPE:
		  table->arg_type[argc] = SLANG_DOUBLE_TYPE;
		  table->double_args[argc++] = atof(buf);
#endif
	       }
	     break;
	  }
     }

   /*                 call function */
   status = (*cmd->cmdfun)(argc, table);

   error:
   if (table->string_args != NULL) for (i = 0; i < argc; i++)
     {
	if (NULL != table->string_args[i])
	  {
	     SLfree (table->string_args[i]);
	     table->string_args[i] = NULL;
	  }
     }
   SLfree ((char *)table->string_args); table->string_args = NULL;
   SLfree ((char *)table->double_args); table->double_args = NULL;
   SLfree ((char *)table->int_args); table->int_args = NULL;
   SLfree ((char *)table->arg_type); table->arg_type = NULL;

   SLfree (buf);
   return status;
}
Esempio n. 19
0
/*
 * smtp_do_bounce() is caled by smtp_do_procmsg() to scan a set of delivery
 * instructions for "5" codes (permanent fatal errors) and produce/deliver
 * a "bounce" message (delivery status notification).
 */
void smtp_do_bounce(char *instr, StrBuf *OMsgTxt)
{
	int i;
	int lines;
	int status;
	char buf[1024];
	char key[1024];
	char addr[1024];
	char dsn[1024];
	char bounceto[1024];
	StrBuf *boundary;
	int num_bounces = 0;
	int bounce_this = 0;
	time_t submitted = 0L;
	struct CtdlMessage *bmsg = NULL;
	int give_up = 0;
	recptypes *valid;
	int successful_bounce = 0;
	static int seq = 0;
	StrBuf *BounceMB;
	long omsgid = (-1);

	syslog(LOG_DEBUG, "smtp_do_bounce() called\n");
	strcpy(bounceto, "");
	boundary = NewStrBufPlain(HKEY("=_Citadel_Multipart_"));

	StrBufAppendPrintf(boundary, "%s_%04x%04x", CtdlGetConfigStr("c_fqdn"), getpid(), ++seq);

	lines = num_tokens(instr, '\n');

	/* See if it's time to give up on delivery of this message */
	for (i=0; i<lines; ++i) {
		extract_token(buf, instr, i, '\n', sizeof buf);
		extract_token(key, buf, 0, '|', sizeof key);
		extract_token(addr, buf, 1, '|', sizeof addr);
		if (!strcasecmp(key, "submitted")) {
			submitted = atol(addr);
		}
	}

	if ( (time(NULL) - submitted) > SMTP_GIVE_UP ) {
		give_up = 1;
	}

	/* Start building our bounce message */

	bmsg = (struct CtdlMessage *) malloc(sizeof(struct CtdlMessage));
	if (bmsg == NULL) return;
	memset(bmsg, 0, sizeof(struct CtdlMessage));
	BounceMB = NewStrBufPlain(NULL, 1024);

	bmsg->cm_magic = CTDLMESSAGE_MAGIC;
	bmsg->cm_anon_type = MES_NORMAL;
	bmsg->cm_format_type = FMT_RFC822;
	CM_SetField(bmsg, eAuthor, HKEY("Citadel"));
	CM_SetField(bmsg, eOriginalRoom, HKEY(MAILROOM));
	CM_SetField(bmsg, eNodeName, CtdlGetConfigStr("c_nodename"), strlen(CtdlGetConfigStr("c_nodename")));
	CM_SetField(bmsg, eMsgSubject, HKEY("Delivery Status Notification (Failure)"));
	StrBufAppendBufPlain(BounceMB, HKEY("Content-type: multipart/mixed; boundary=\""), 0);
	StrBufAppendBuf(BounceMB, boundary, 0);
	StrBufAppendBufPlain(BounceMB, HKEY("\"\r\n"), 0);
	StrBufAppendBufPlain(BounceMB, HKEY("MIME-Version: 1.0\r\n"), 0);
	StrBufAppendBufPlain(BounceMB, HKEY("X-Mailer: " CITADEL "\r\n"), 0);

	StrBufAppendBufPlain(
		BounceMB,
		HKEY("\r\nThis is a multipart message in MIME format."
		     "\r\n\r\n"), 0);

	StrBufAppendBufPlain(BounceMB, HKEY("--"), 0);
	StrBufAppendBuf(BounceMB, boundary, 0);
	StrBufAppendBufPlain(BounceMB, HKEY("\r\n"), 0);
	StrBufAppendBufPlain(BounceMB,
			     HKEY("Content-type: text/plain\r\n\r\n"), 0);

	if (give_up)
	{
		StrBufAppendBufPlain(
			BounceMB,
			HKEY("A message you sent could not be delivered "
			     "to some or all of its recipients\ndue to "
			     "prolonged unavailability of its destination(s).\n"
			     "Giving up on the following addresses:\n\n"), 0);
	}
	else
	{
		StrBufAppendBufPlain(
			BounceMB,
			HKEY("A message you sent could not be delivered "
			     "to some or all of its recipients.\n"
			     "The following addresses were undeliverable:\n\n"
				), 0);
	}

	/*
	 * Now go through the instructions checking for stuff.
	 */
	for (i=0; i<lines; ++i) {
		long addrlen;
		long dsnlen;
		extract_token(buf, instr, i, '\n', sizeof buf);
		extract_token(key, buf, 0, '|', sizeof key);
		addrlen = extract_token(addr, buf, 1, '|', sizeof addr);
		status = extract_int(buf, 2);
		dsnlen = extract_token(dsn, buf, 3, '|', sizeof dsn);
		bounce_this = 0;

		syslog(LOG_DEBUG, "key=<%s> addr=<%s> status=%d dsn=<%s>\n",
		       key, addr, status, dsn);

		if (!strcasecmp(key, "bounceto")) {
			strcpy(bounceto, addr);
		}

		if (!strcasecmp(key, "msgid")) {
			omsgid = atol(addr);
		}

		if (!strcasecmp(key, "remote")) {
			if (status == 5) bounce_this = 1;
			if (give_up) bounce_this = 1;
		}

		if (bounce_this) {
			++num_bounces;

			StrBufAppendBufPlain(BounceMB, addr, addrlen, 0);
			StrBufAppendBufPlain(BounceMB, HKEY(": "), 0);
			StrBufAppendBufPlain(BounceMB, dsn, dsnlen, 0);
			StrBufAppendBufPlain(BounceMB, HKEY("\r\n"), 0);

			remove_token(instr, i, '\n');
			--i;
			--lines;
		}
	}

	/* Attach the original message */
	if (omsgid >= 0) {
		StrBufAppendBufPlain(BounceMB, HKEY("--"), 0);
		StrBufAppendBuf(BounceMB, boundary, 0);
		StrBufAppendBufPlain(BounceMB, HKEY("\r\n"), 0);

		StrBufAppendBufPlain(
			BounceMB,
			HKEY("Content-type: message/rfc822\r\n"), 0);

		StrBufAppendBufPlain(
			BounceMB,
			HKEY("Content-Transfer-Encoding: 7bit\r\n"), 0);

		StrBufAppendBufPlain(
			BounceMB,
			HKEY("Content-Disposition: inline\r\n"), 0);

		StrBufAppendBufPlain(BounceMB, HKEY("\r\n"), 0);

		if (OMsgTxt == NULL) {
			CC->redirect_buffer = NewStrBufPlain(NULL, SIZ);
			CtdlOutputMsg(omsgid,
				      MT_RFC822,
				      HEADERS_ALL,
				      0, 1, NULL, 0,
				      NULL, NULL, NULL);

			StrBufAppendBuf(BounceMB, CC->redirect_buffer, 0);
			FreeStrBuf(&CC->redirect_buffer);
		}
		else {
			StrBufAppendBuf(BounceMB, OMsgTxt, 0);
		}
	}

	/* Close the multipart MIME scope */
	StrBufAppendBufPlain(BounceMB, HKEY("--"), 0);
	StrBufAppendBuf(BounceMB, boundary, 0);
	StrBufAppendBufPlain(BounceMB, HKEY("--\r\n"), 0);
	CM_SetAsFieldSB(bmsg, eMesageText, &BounceMB);

	/* Deliver the bounce if there's anything worth mentioning */
	syslog(LOG_DEBUG, "num_bounces = %d\n", num_bounces);
	if (num_bounces > 0) {

		/* First try the user who sent the message */
		if (IsEmptyStr(bounceto))
			syslog(LOG_ERR, "No bounce address specified\n");
		else
			syslog(LOG_DEBUG, "bounce to user <%s>\n", bounceto);
		/* Can we deliver the bounce to the original sender? */
		valid = validate_recipients(bounceto,
					    smtp_get_Recipients (),
					    0);
		if (valid != NULL) {
			if (valid->num_error == 0) {
				CtdlSubmitMsg(bmsg, valid, "", QP_EADDR);
				successful_bounce = 1;
			}
		}

		/* If not, post it in the Aide> room */
		if (successful_bounce == 0) {
			CtdlSubmitMsg(bmsg, NULL, CtdlGetConfigStr("c_aideroom"), QP_EADDR);
		}

		/* Free up the memory we used */
		if (valid != NULL) {
			free_recipients(valid);
		}
	}
	FreeStrBuf(&boundary);
	CM_Free(bmsg);
	syslog(LOG_DEBUG, "Done processing bounces\n");
}
Esempio n. 20
0
/* 
 * Get or set global configuration options
 *
 * IF YOU ADD OR CHANGE FIELDS HERE, YOU *MUST* DOCUMENT YOUR CHANGES AT:
 * http://www.citadel.org/doku.php?id=documentation:applicationprotocol
 *
 */
void cmd_conf(char *argbuf)
{
	char cmd[16];
	char buf[256];
	int a;
	char *confptr;
	char confname[128];

	if (CtdlAccessCheck(ac_aide)) return;

	extract_token(cmd, argbuf, 0, '|', sizeof cmd);
	if (!strcasecmp(cmd, "GET")) {
		cprintf("%d Configuration...\n", LISTING_FOLLOWS);
		cprintf("%s\n", config.c_nodename);
		cprintf("%s\n", config.c_fqdn);
		cprintf("%s\n", config.c_humannode);
		cprintf("%s\n", config.c_phonenum);
		cprintf("%d\n", config.c_creataide);
		cprintf("%d\n", config.c_sleeping);
		cprintf("%d\n", config.c_initax);
		cprintf("%d\n", config.c_regiscall);
		cprintf("%d\n", config.c_twitdetect);
		cprintf("%s\n", config.c_twitroom);
		cprintf("%s\n", config.c_moreprompt);
		cprintf("%d\n", config.c_restrict);
		cprintf("%s\n", config.c_site_location);
		cprintf("%s\n", config.c_sysadm);
		cprintf("%d\n", config.c_maxsessions);
		cprintf("xxx\n"); /* placeholder -- field no longer in use */
		cprintf("%d\n", config.c_userpurge);
		cprintf("%d\n", config.c_roompurge);
		cprintf("%s\n", config.c_logpages);
		cprintf("%d\n", config.c_createax);
		cprintf("%ld\n", config.c_maxmsglen);
		cprintf("%d\n", config.c_min_workers);
		cprintf("%d\n", config.c_max_workers);
		cprintf("%d\n", config.c_pop3_port);
		cprintf("%d\n", config.c_smtp_port);
		cprintf("%d\n", config.c_rfc822_strict_from);
		cprintf("%d\n", config.c_aide_zap);
		cprintf("%d\n", config.c_imap_port);
		cprintf("%ld\n", config.c_net_freq);
		cprintf("%d\n", config.c_disable_newu);
		cprintf("1\n");	/* niu */
		cprintf("%d\n", config.c_purge_hour);
#ifdef HAVE_LDAP
		cprintf("%s\n", config.c_ldap_host);
		cprintf("%d\n", config.c_ldap_port);
		cprintf("%s\n", config.c_ldap_base_dn);
		cprintf("%s\n", config.c_ldap_bind_dn);
		cprintf("%s\n", config.c_ldap_bind_pw);
#else
		cprintf("\n");
		cprintf("0\n");
		cprintf("\n");
		cprintf("\n");
		cprintf("\n");
#endif
		cprintf("%s\n", config.c_ip_addr);
		cprintf("%d\n", config.c_msa_port);
		cprintf("%d\n", config.c_imaps_port);
		cprintf("%d\n", config.c_pop3s_port);
		cprintf("%d\n", config.c_smtps_port);
		cprintf("%d\n", config.c_enable_fulltext);
		cprintf("%d\n", config.c_auto_cull);
		cprintf("1\n");
		cprintf("%d\n", config.c_allow_spoofing);
		cprintf("%d\n", config.c_journal_email);
		cprintf("%d\n", config.c_journal_pubmsgs);
		cprintf("%s\n", config.c_journal_dest);
		cprintf("%s\n", config.c_default_cal_zone);
		cprintf("%d\n", config.c_pftcpdict_port);
		cprintf("%d\n", config.c_managesieve_port);
	        cprintf("%d\n", config.c_auth_mode);
	        cprintf("%s\n", config.c_funambol_host);
	        cprintf("%d\n", config.c_funambol_port);
	        cprintf("%s\n", config.c_funambol_source);
	        cprintf("%s\n", config.c_funambol_auth);
		cprintf("%d\n", config.c_rbl_at_greeting);
		cprintf("%s\n", config.c_master_user);
		cprintf("%s\n", config.c_master_pass);
		cprintf("%s\n", config.c_pager_program);
		cprintf("%d\n", config.c_imap_keep_from);
		cprintf("%d\n", config.c_xmpp_c2s_port);
		cprintf("%d\n", config.c_xmpp_s2s_port);
		cprintf("%ld\n", config.c_pop3_fetch);
		cprintf("%ld\n", config.c_pop3_fastest);
		cprintf("%d\n", config.c_spam_flag_only);
		cprintf("%d\n", config.c_guest_logins);
		cprintf("%d\n", config.c_port_number);
		cprintf("%d\n", config.c_ctdluid);
		cprintf("%d\n", config.c_nntp_port);
		cprintf("%d\n", config.c_nntps_port);
		cprintf("000\n");
	}

	else if (!strcasecmp(cmd, "SET")) {
		unbuffer_output();
		cprintf("%d Send configuration...\n", SEND_LISTING);
		a = 0;
		while (client_getln(buf, sizeof buf) >= 0 && strcmp(buf, "000")) {
			switch (a) {
			case 0:
				configlen.c_nodename = safestrncpy(config.c_nodename, buf,
								   sizeof config.c_nodename);
				break;
			case 1:
				configlen.c_fqdn = safestrncpy(config.c_fqdn, buf,
							       sizeof config.c_fqdn);
				break;
			case 2:
				configlen.c_humannode = safestrncpy(config.c_humannode, buf,
								    sizeof config.c_humannode);
				break;
			case 3:
				configlen.c_phonenum = safestrncpy(config.c_phonenum, buf,
								   sizeof config.c_phonenum);
				break;
			case 4:
				config.c_creataide = atoi(buf);
				break;
			case 5:
				config.c_sleeping = atoi(buf);
				break;
			case 6:
				config.c_initax = atoi(buf);
				if (config.c_initax < 1)
					config.c_initax = 1;
				if (config.c_initax > 6)
					config.c_initax = 6;
				break;
			case 7:
				config.c_regiscall = atoi(buf);
				if (config.c_regiscall != 0)
					config.c_regiscall = 1;
				break;
			case 8:
				config.c_twitdetect = atoi(buf);
				if (config.c_twitdetect != 0)
					config.c_twitdetect = 1;
				break;
			case 9:
				configlen.c_twitroom = safestrncpy(config.c_twitroom, buf,
								   sizeof config.c_twitroom);
				break;
			case 10:
				configlen.c_moreprompt = safestrncpy(config.c_moreprompt, buf,
								     sizeof config.c_moreprompt);
				break;
			case 11:
				config.c_restrict = atoi(buf);
				if (config.c_restrict != 0)
					config.c_restrict = 1;
				break;
			case 12:
				configlen.c_site_location = safestrncpy(
					config.c_site_location, buf,
					sizeof config.c_site_location);
				break;
			case 13:
				configlen.c_sysadm = safestrncpy(config.c_sysadm, buf,
								 sizeof config.c_sysadm);
				break;
			case 14:
				config.c_maxsessions = atoi(buf);
				if (config.c_maxsessions < 0)
					config.c_maxsessions = 0;
				break;
			case 15:
				/* placeholder -- field no longer in use */
				break;
			case 16:
				config.c_userpurge = atoi(buf);
				break;
			case 17:
				config.c_roompurge = atoi(buf);
				break;
			case 18:
				configlen.c_logpages = safestrncpy(config.c_logpages, buf,
								   sizeof config.c_logpages);
				break;
			case 19:
				config.c_createax = atoi(buf);
				if (config.c_createax < 1)
					config.c_createax = 1;
				if (config.c_createax > 6)
					config.c_createax = 6;
				break;
			case 20:
				if (atoi(buf) >= 8192)
					config.c_maxmsglen = atoi(buf);
				break;
			case 21:
				if (atoi(buf) >= 2)
					config.c_min_workers = atoi(buf);
			case 22:
				if (atoi(buf) >= config.c_min_workers)
					config.c_max_workers = atoi(buf);
			case 23:
				config.c_pop3_port = atoi(buf);
				break;
			case 24:
				config.c_smtp_port = atoi(buf);
				break;
			case 25:
				config.c_rfc822_strict_from = atoi(buf);
				break;
			case 26:
				config.c_aide_zap = atoi(buf);
				if (config.c_aide_zap != 0)
					config.c_aide_zap = 1;
				break;
			case 27:
				config.c_imap_port = atoi(buf);
				break;
			case 28:
				config.c_net_freq = atol(buf);
				break;
			case 29:
				config.c_disable_newu = atoi(buf);
				if (config.c_disable_newu != 0)
					config.c_disable_newu = 1;
				break;
			case 30:
				/* niu */
				break;
			case 31:
				if ((config.c_purge_hour >= 0)
				    && (config.c_purge_hour <= 23)) {
					config.c_purge_hour = atoi(buf);
				}
				break;
#ifdef HAVE_LDAP
			case 32:
				configlen.c_ldap_host = safestrncpy(config.c_ldap_host, buf,
								    sizeof config.c_ldap_host);
				break;
			case 33:
				config.c_ldap_port = atoi(buf);
				break;
			case 34:
				configlen.c_ldap_base_dn = safestrncpy(config.c_ldap_base_dn, buf,
								       sizeof config.c_ldap_base_dn);
				break;
			case 35:
				configlen.c_ldap_bind_dn = safestrncpy(config.c_ldap_bind_dn, buf,
								       sizeof config.c_ldap_bind_dn);
				break;
			case 36:
				configlen.c_ldap_bind_pw = safestrncpy(config.c_ldap_bind_pw, buf,
								       sizeof config.c_ldap_bind_pw);
				break;
#endif
			case 37:
				configlen.c_ip_addr = safestrncpy(config.c_ip_addr, buf,
								  sizeof config.c_ip_addr);
			case 38:
				config.c_msa_port = atoi(buf);
				break;
			case 39:
				config.c_imaps_port = atoi(buf);
				break;
			case 40:
				config.c_pop3s_port = atoi(buf);
				break;
			case 41:
				config.c_smtps_port = atoi(buf);
				break;
			case 42:
				config.c_enable_fulltext = atoi(buf);
				break;
			case 43:
				config.c_auto_cull = atoi(buf);
				break;
			case 44:
				/* niu */
				break;
			case 45:
				config.c_allow_spoofing = atoi(buf);
				break;
			case 46:
				config.c_journal_email = atoi(buf);
				break;
			case 47:
				config.c_journal_pubmsgs = atoi(buf);
				break;
			case 48:
				configlen.c_journal_dest = safestrncpy(config.c_journal_dest, buf,
								       sizeof config.c_journal_dest);
			case 49:
				configlen.c_default_cal_zone = safestrncpy(
					config.c_default_cal_zone, buf,
					sizeof config.c_default_cal_zone);
				break;
			case 50:
				config.c_pftcpdict_port = atoi(buf);
				break;
			case 51:
				config.c_managesieve_port = atoi(buf);
				break;
			case 52:
				config.c_auth_mode = atoi(buf);
			case 53:
				configlen.c_funambol_host = safestrncpy(
					config.c_funambol_host, buf,
					sizeof config.c_funambol_host);
				break;
			case 54:
				config.c_funambol_port = atoi(buf);
				break;
			case 55:
				configlen.c_funambol_source = safestrncpy(
					config.c_funambol_source, buf, 
					sizeof config.c_funambol_source);
				break;
			case 56:
				configlen.c_funambol_auth = safestrncpy(
					config.c_funambol_auth, buf,
					sizeof config.c_funambol_auth);
				break;
			case 57:
				config.c_rbl_at_greeting = atoi(buf);
				break;
			case 58:
				configlen.c_master_user = safestrncpy(
					config.c_master_user,
					buf, sizeof config.c_master_user);
				break;
			case 59:
				configlen.c_master_pass = safestrncpy(
					config.c_master_pass, buf, sizeof config.c_master_pass);
				break;
			case 60:
				configlen.c_pager_program = safestrncpy(
					config.c_pager_program,	buf, sizeof config.c_pager_program);
				break;
			case 61:
				config.c_imap_keep_from = atoi(buf);
				break;
			case 62:
				config.c_xmpp_c2s_port = atoi(buf);
				break;
			case 63:
				config.c_xmpp_s2s_port = atoi(buf);
				break;
			case 64:
				config.c_pop3_fetch = atol(buf);
				break;
			case 65:
				config.c_pop3_fastest = atol(buf);
				break;
			case 66:
				config.c_spam_flag_only = atoi(buf);
				break;
			case 67:
				config.c_guest_logins = atoi(buf);
				break;
			case 68:
				config.c_port_number = atoi(buf);
				break;
			case 69:
				config.c_ctdluid = atoi(buf);
				break;
			case 70:
				config.c_nntp_port = atoi(buf);
				break;
			case 71:
				config.c_nntps_port = atoi(buf);
				break;
			}
			++a;
		}
		put_config();
		snprintf(buf, sizeof buf,
			"The global system configuration has been edited by %s.\n",
			 (CC->logged_in ? CC->curr_user : "******")
		);
		CtdlAideMessage(buf,"Citadel Configuration Manager Message");

		if (!IsEmptyStr(config.c_logpages))
			CtdlCreateRoom(config.c_logpages, 3, "", 0, 1, 1, VIEW_BBS);

		/* If full text indexing has been disabled, invalidate the
		 * index so it doesn't try to use it later.
		 */
		if (config.c_enable_fulltext == 0) {
			CitControl.fulltext_wordbreaker = 0;
			put_control();
		}
	}

	else if (!strcasecmp(cmd, "GETSYS")) {
		extract_token(confname, argbuf, 1, '|', sizeof confname);
		confptr = CtdlGetSysConfig(confname);
		if (confptr != NULL) {
			long len; 

			len = strlen(confptr);
			cprintf("%d %s\n", LISTING_FOLLOWS, confname);
			client_write(confptr, len);
			if ((len > 0) && (confptr[len - 1] != 10))
				client_write("\n", 1);
			cprintf("000\n");
			free(confptr);
		} else {
			cprintf("%d No such configuration.\n",
				ERROR + ILLEGAL_VALUE);
		}
	}

	else if (!strcasecmp(cmd, "PUTSYS")) {
		extract_token(confname, argbuf, 1, '|', sizeof confname);
		unbuffer_output();
		cprintf("%d %s\n", SEND_LISTING, confname);
		confptr = CtdlReadMessageBody(HKEY("000"), config.c_maxmsglen, NULL, 0, 0);
		CtdlPutSysConfig(confname, confptr);
		free(confptr);
	}

	else {
		cprintf("%d Illegal option(s) specified.\n",
			ERROR + ILLEGAL_VALUE);
	}
}
Esempio n. 21
0
/*
 * Fetch a message from the server and extract a vNote from it
 */
struct vnote *vnote_new_from_msg(long msgnum,int unread) 
{
	StrBuf *Buf;
	StrBuf *Data = NULL;
	const char *bptr;
	int Done = 0;
	char uid_from_headers[256];
	char mime_partnum[256];
	char mime_filename[256];
	char mime_content_type[256];
	char mime_disposition[256];
	char relevant_partnum[256];
	int phase = 0;				/* 0 = citadel headers, 1 = mime headers, 2 = body */
	char msg4_content_type[256] = "";
	char msg4_content_encoding[256] = "";
	int msg4_content_length = 0;
	struct vnote *vnote_from_body = NULL;
	int vnote_inline = 0;			/* 1 = MSG4 gave us a text/x-vnote top level */

	relevant_partnum[0] = '\0';
	serv_printf("MSG4 %ld", msgnum);	/* we need the mime headers */
	Buf = NewStrBuf();
	StrBuf_ServGetln(Buf);
	if (GetServerStatus(Buf, NULL) != 1) {
		FreeStrBuf (&Buf);
		return NULL;
	}
	while ((StrBuf_ServGetln(Buf)>=0) && !Done) {
		if ( (StrLength(Buf)==3) && 
		     !strcmp(ChrPtr(Buf), "000")) {
			Done = 1;
			break;
		}
		bptr = ChrPtr(Buf);
		switch (phase) {
		case 0:
			if (!strncasecmp(bptr, "exti=", 5)) {
				safestrncpy(uid_from_headers, &(ChrPtr(Buf)[5]), sizeof uid_from_headers);
			}
			else if (!strncasecmp(bptr, "part=", 5)) {
				extract_token(mime_filename, &bptr[5], 1, '|', sizeof mime_filename);
				extract_token(mime_partnum, &bptr[5], 2, '|', sizeof mime_partnum);
				extract_token(mime_disposition, &bptr[5], 3, '|', sizeof mime_disposition);
				extract_token(mime_content_type, &bptr[5], 4, '|', sizeof mime_content_type);

				if (!strcasecmp(mime_content_type, "text/vnote")) {
					strcpy(relevant_partnum, mime_partnum);
				}
			}
			else if ((phase == 0) && (!strncasecmp(bptr, "text", 4))) {
				phase = 1;
			}
		break;
		case 1:
			if (!IsEmptyStr(bptr)) {
				if (!strncasecmp(bptr, "Content-type: ", 14)) {
					safestrncpy(msg4_content_type, &bptr[14], sizeof msg4_content_type);
					striplt(msg4_content_type);
				}
				else if (!strncasecmp(bptr, "Content-transfer-encoding: ", 27)) {
					safestrncpy(msg4_content_encoding, &bptr[27], sizeof msg4_content_encoding);
					striplt(msg4_content_type);
				}
				else if ((!strncasecmp(bptr, "Content-length: ", 16))) {
					msg4_content_length = atoi(&bptr[16]);
				}
				break;
			}
			else {
				phase++;
				if ((msg4_content_length > 0)
				    && ( !strcasecmp(msg4_content_encoding, "7bit"))
				    && (!strcasecmp(msg4_content_type, "text/vnote"))
				) { 
					vnote_inline = 1;
				}
			}
		case 2:
			if (vnote_inline) {
				Data = NewStrBufPlain(NULL, msg4_content_length * 2);
				if (msg4_content_length > 0) {
					StrBuf_ServGetBLOBBuffered(Data, msg4_content_length);
					phase ++;
				}
				else {
					StrBufAppendBuf(Data, Buf, 0);
					StrBufAppendBufPlain(Data, "\r\n", 1, 0);
				}
			}
		case 3:
			if (vnote_inline) {
				StrBufAppendBuf(Data, Buf, 0);
			}
		}
	}
	FreeStrBuf(&Buf);

	/* If MSG4 didn't give us the part we wanted, but we know that we can find it
	 * as one of the other MIME parts, attempt to load it now.
	 */
	if ((!vnote_inline) && (!IsEmptyStr(relevant_partnum))) {
		Data = load_mimepart(msgnum, relevant_partnum);
	}

	if (StrLength(Data) > 0) {
		if (IsEmptyStr(uid_from_headers)) {
			/* Convert an old-style note to a vNote */
			vnote_from_body = vnote_new();
			vnote_from_body->uid = strdup(uid_from_headers);
			vnote_from_body->color_red = pastel_palette[3][0];
			vnote_from_body->color_green = pastel_palette[3][1];
			vnote_from_body->color_blue = pastel_palette[3][2];
			vnote_from_body->body = malloc(StrLength(Data) + 1);
			vnote_from_body->body[0] = 0;
			memcpy(vnote_from_body->body, ChrPtr(Data), StrLength(Data) + 1);
			FreeStrBuf(&Data);
			return vnote_from_body;
		}
		else {
			char *Buf = SmashStrBuf(&Data);
			
			struct vnote *v = vnote_new_from_str(Buf);
			free(Buf);
			return(v);
		}
	}
	return NULL;
}
Esempio n. 22
0
//
// The LAST and NEXT commands are so similar that they are handled by a single function.
//
void nntp_last_next(const char *cmd) {
	if (CtdlAccessCheck(ac_logged_in_or_guest)) return;

	citnntp *nntpstate = (citnntp *) CC->session_specific_data;
	char which_command[16];
	int acmd = 0;

	// We're going to store one of these values in the variable 'acmd' so that
	// we can quickly check later which version of the output we want.
	enum {
		NNTP_LAST,
		NNTP_NEXT
	};

	extract_token(which_command, cmd, 0, ' ', sizeof which_command);

	if (!strcasecmp(which_command, "last")) {
		acmd = NNTP_LAST;
	}
	else if (!strcasecmp(which_command, "next")) {
		acmd = NNTP_NEXT;
	}
	else {
		cprintf("500 I'm afraid I can't do that.\r\n");
		return;
	}

	// ok, here we go ... fetch the msglist so we can figure out our place in the universe
	struct nntp_msglist nm;
	int i = 0;
	long selected_msgnum = 0;
	char *message_id = NULL;

	nm = nntp_fetch_msglist(&CC->room);
	if ((nm.num_msgs < 0) || (nm.msgnums == NULL)) {
		cprintf("500 something bad happened\r\n");
		return;
	}

	if ( (acmd == NNTP_LAST) && (nm.num_msgs == 0) ) {
			cprintf("422 no previous article in this group\r\n");	// nothing here
	}

	else if ( (acmd == NNTP_LAST) && (nntpstate->current_article_number <= nm.msgnums[0]) ) {
			cprintf("422 no previous article in this group\r\n");	// already at the beginning
	}

	else if (acmd == NNTP_LAST) {
		for (i=0; ((i<nm.num_msgs)&&(selected_msgnum<=0)); ++i) {
			if ( (nm.msgnums[i] >= nntpstate->current_article_number) && (i > 0) ) {
				selected_msgnum = nm.msgnums[i-1];
			}
		}
		if (selected_msgnum > 0) {
			nntpstate->current_article_number = selected_msgnum;
			message_id = message_id_from_msgnum(nntpstate->current_article_number);
			cprintf("223 %ld <%s>\r\n", nntpstate->current_article_number, message_id);
			if (message_id) free(message_id);
		}
		else {
			cprintf("422 no previous article in this group\r\n");
		}
	}

	else if ( (acmd == NNTP_NEXT) && (nm.num_msgs == 0) ) {
			cprintf("421 no next article in this group\r\n");	// nothing here
	}

	else if ( (acmd == NNTP_NEXT) && (nntpstate->current_article_number >= nm.msgnums[nm.num_msgs-1]) ) {
			cprintf("421 no next article in this group\r\n");	// already at the end
	}

	else if (acmd == NNTP_NEXT) {
		for (i=0; ((i<nm.num_msgs)&&(selected_msgnum<=0)); ++i) {
			if (nm.msgnums[i] > nntpstate->current_article_number) {
				selected_msgnum = nm.msgnums[i];
			}
		}
		if (selected_msgnum > 0) {
			nntpstate->current_article_number = selected_msgnum;
			message_id = message_id_from_msgnum(nntpstate->current_article_number);
			cprintf("223 %ld <%s>\r\n", nntpstate->current_article_number, message_id);
			if (message_id) free(message_id);
		}
		else {
			cprintf("421 no next article in this group\r\n");
		}
	}

	// should never get here
	else {
		cprintf("500 internal error\r\n");
	}

	if (nm.msgnums != NULL) {
		free(nm.msgnums);
	}

}
Esempio n. 23
0
/*
 * Called by JournalRunQueue() to send an individual message.
 */
void JournalRunQueueMsg(struct jnlq *jmsg) {

	struct CtdlMessage *journal_msg = NULL;
	recptypes *journal_recps = NULL;
	StrBuf *message_text = NULL;
	char mime_boundary[256];
	long mblen;
	long rfc822len;
	char recipient[256];
	char inetemail[256];
	static int seq = 0;
	int i;

	if (jmsg == NULL)
		return;
	journal_recps = validate_recipients(config.c_journal_dest, NULL, 0);
	if (journal_recps != NULL) {

		if (  (journal_recps->num_local > 0)
		   || (journal_recps->num_internet > 0)
		   || (journal_recps->num_ignet > 0)
		   || (journal_recps->num_room > 0)
		) {

			/*
			 * Construct journal message.
			 * Note that we are transferring ownership of some of the memory here.
			 */
			journal_msg = malloc(sizeof(struct CtdlMessage));
			memset(journal_msg, 0, sizeof(struct CtdlMessage));
			journal_msg->cm_magic = CTDLMESSAGE_MAGIC;
			journal_msg->cm_anon_type = MES_NORMAL;
			journal_msg->cm_format_type = FMT_RFC822;
			CM_SetField(journal_msg, eJournal, HKEY("is journal"));
			CM_SetField(journal_msg, eAuthor, jmsg->from, strlen(jmsg->from));
			CM_SetField(journal_msg, eNodeName, jmsg->node, strlen(jmsg->node));
			CM_SetField(journal_msg, erFc822Addr, jmsg->rfca, strlen(jmsg->rfca));
			CM_SetField(journal_msg, eMsgSubject, jmsg->subj, strlen(jmsg->subj));

			mblen = snprintf(mime_boundary, sizeof(mime_boundary),
					 "--Citadel-Journal-%08lx-%04x--", time(NULL), ++seq);
			rfc822len = strlen(jmsg->rfc822);
		       
			message_text = NewStrBufPlain(NULL, rfc822len + sizeof(recptypes) + 1024);

			/*
			 * Here is where we begin to compose the journalized message.
			 * NOTE: the superfluous "Content-Identifer: ExJournalReport" header was
			 *       requested by a paying customer, and yes, it is intentionally
			 *       spelled wrong.  Do NOT remove or change it.
			 */
			StrBufAppendBufPlain(
				message_text, 
				HKEY("Content-type: multipart/mixed; boundary=\""), 0);

			StrBufAppendBufPlain(message_text, mime_boundary, mblen, 0);

			StrBufAppendBufPlain(
				message_text, 
				HKEY("\"\r\n"
				     "Content-Identifer: ExJournalReport\r\n"
				     "MIME-Version: 1.0\r\n"
				     "\n"
				     "--"), 0);

			StrBufAppendBufPlain(message_text, mime_boundary, mblen, 0);

			StrBufAppendBufPlain(
				message_text, 
				HKEY("\r\n"
				     "Content-type: text/plain\r\n"
				     "\r\n"
				     "Sender: "), 0);

			if (CM_IsEmpty(journal_msg, eAuthor))
				StrBufAppendBufPlain(
					message_text, 
					journal_msg->cm_fields[eAuthor], -1, 0);
			else
				StrBufAppendBufPlain(
					message_text, 
					HKEY("(null)"), 0);

			if (!CM_IsEmpty(journal_msg, erFc822Addr)) {
				StrBufAppendPrintf(message_text, " <%s>",
						   journal_msg->cm_fields[erFc822Addr]);
			}
			else if (!CM_IsEmpty(journal_msg, eNodeName)) {
				StrBufAppendPrintf(message_text, " @ %s",
						   journal_msg->cm_fields[eNodeName]);
			}
			else
				StrBufAppendBufPlain(
					message_text, 
					HKEY(" "), 0);

			StrBufAppendBufPlain(
				message_text, 
				HKEY("\r\n"
				     "Message-ID: <"), 0);

			StrBufAppendBufPlain(message_text, jmsg->msgn, -1, 0);
			StrBufAppendBufPlain(
				message_text, 
				HKEY(">\r\n"
				     "Recipients:\r\n"), 0);

			if (jmsg->recps.num_local > 0) {
				for (i=0; i<jmsg->recps.num_local; ++i) {
					extract_token(recipient, jmsg->recps.recp_local,
							i, '|', sizeof recipient);
					local_to_inetemail(inetemail, recipient, sizeof inetemail);
					StrBufAppendPrintf(message_text, 
							   "	%s <%s>\r\n", recipient, inetemail);
				}
			}

			if (jmsg->recps.num_ignet > 0) {
				for (i=0; i<jmsg->recps.num_ignet; ++i) {
					extract_token(recipient, jmsg->recps.recp_ignet,
							i, '|', sizeof recipient);
					StrBufAppendPrintf(message_text, 
							   "	%s\r\n", recipient);
				}
			}

			if (jmsg->recps.num_internet > 0) {
				for (i=0; i<jmsg->recps.num_internet; ++i) {
					extract_token(recipient, jmsg->recps.recp_internet,
							i, '|', sizeof recipient);
					StrBufAppendPrintf(message_text, 
						"	%s\r\n", recipient);
				}
			}

			StrBufAppendBufPlain(
				message_text, 
				HKEY("\r\n"
				     "--"), 0);

			StrBufAppendBufPlain(message_text, mime_boundary, mblen, 0);

			StrBufAppendBufPlain(
				message_text, 
				HKEY("\r\n"
				     "Content-type: message/rfc822\r\n"
				     "\r\n"), 0);

			StrBufAppendBufPlain(message_text, jmsg->rfc822, rfc822len, 0);

			StrBufAppendBufPlain(
				message_text, 
				HKEY("--"), 0);

			StrBufAppendBufPlain(message_text, mime_boundary, mblen, 0);

			StrBufAppendBufPlain(
				message_text, 
				HKEY("--\r\n"), 0);

			CM_SetAsFieldSB(journal_msg, eMesageText, &message_text);
			free(jmsg->rfc822);
			free(jmsg->msgn);
			jmsg->rfc822 = NULL;
			jmsg->msgn = NULL;
			
			/* Submit journal message */
			CtdlSubmitMsg(journal_msg, journal_recps, "", 0);
			CM_Free(journal_msg);
		}

		free_recipients(journal_recps);
	}

	/* We are responsible for freeing this memory. */
	free(jmsg);
}
Esempio n. 24
0
/*
 * The pathname is always going to be /groupdav/room_name/euid
 */
void dav_delete(void) 
{
	wcsession *WCC = WC;
	char dav_uid[SIZ];
	long dav_msgnum = (-1);
	char buf[SIZ];
	int n = 0;
	StrBuf *dav_roomname = NewStrBuf();
	
	/* Now extract the message euid */
	n = StrBufNum_tokens(WCC->Hdr->HR.ReqLine, '/');
	extract_token(dav_uid, ChrPtr(WCC->Hdr->HR.ReqLine), n-1, '/', sizeof dav_uid);
	StrBufExtract_token(dav_roomname, WCC->Hdr->HR.ReqLine, 0, '/');

	///* What's left is the room name.  Remove trailing slashes. */
	//len = StrLength(WCC->Hdr->HR.ReqLine);
	//if ((len > 0) && (ChrPtr(WCC->Hdr->HR.ReqLinee)[len-1] == '/')) {
	//	StrBufCutRight(WCC->Hdr->HR.ReqLine, 1);
	//}
	//StrBufCutLeft(WCC->Hdr->HR.ReqLine, 1);

	/* Go to the correct room. */
	if (strcasecmp(ChrPtr(WC->CurRoom.name), ChrPtr(dav_roomname))) {
		gotoroom(dav_roomname);
	}
	if (strcasecmp(ChrPtr(WC->CurRoom.name), ChrPtr(dav_roomname))) {
		hprintf("HTTP/1.1 404 not found\r\n");
		dav_common_headers();
		hprintf("Content-Length: 0\r\n\r\n");
		begin_burst();
		end_burst();
		FreeStrBuf(&dav_roomname);
		return;
	}

	dav_msgnum = locate_message_by_uid(dav_uid);

	/*
	 * If no item exists with the requested uid ... simple error.
	 */
	if (dav_msgnum < 0L) {
		hprintf("HTTP/1.1 404 Not Found\r\n");
		dav_common_headers();
		hprintf("Content-Length: 0\r\n\r\n");
		begin_burst();
		end_burst();
		FreeStrBuf(&dav_roomname);
		return;
	}

	/*
	 * It's there ... check the ETag and make sure it matches
	 * the message number.
	 */
	if (StrLength(WCC->Hdr->HR.dav_ifmatch) > 0) {
		if (StrTol(WCC->Hdr->HR.dav_ifmatch) != dav_msgnum) {
			hprintf("HTTP/1.1 412 Precondition Failed\r\n");
			dav_common_headers();
			hprintf("Content-Length: 0\r\n\r\n");
			begin_burst();
			end_burst();
			FreeStrBuf(&dav_roomname);
			return;
		}
	}

	/*
	 * Ok, attempt to delete the item.
	 */
	serv_printf("DELE %ld", dav_msgnum);
	serv_getln(buf, sizeof buf);
	if (buf[0] == '2') {
		hprintf("HTTP/1.1 204 No Content\r\n");	/* success */
		dav_common_headers();
		hprintf("Content-Length: 0\r\n\r\n");
		begin_burst();
		end_burst();
	}
	else {
		hprintf("HTTP/1.1 403 Forbidden\r\n");	/* access denied */
		dav_common_headers();
		hprintf("Content-Length: 0\r\n\r\n");
		begin_burst();
		end_burst();
	}
	FreeStrBuf(&dav_roomname);
	return;
}
/*  Converts a PEM encoded file into its binary form
 *
 *  RFC 1421 Privacy Enhancement for Electronic Mail, February 1993
 *  RFC 934 Message Encapsulation, January 1985
 */
err_t pem_to_bin(chunk_t *blob, chunk_t *passphrase, bool *pgp)
{
	typedef enum {
		PEM_PRE    = 0,
		PEM_MSG    = 1,
		PEM_HEADER = 2,
		PEM_BODY   = 3,
		PEM_POST   = 4,
		PEM_ABORT  = 5
	} state_t;

	encryption_algorithm_t alg = ENCR_UNDEFINED;
	size_t key_size = 0;

	bool encrypted = FALSE;

	state_t state  = PEM_PRE;

	chunk_t src    = *blob;
	chunk_t dst    = *blob;
	chunk_t line   = CHUNK_INITIALIZER;
	chunk_t iv     = CHUNK_INITIALIZER;

	u_char iv_buf[16]; /* MD5 digest size */

	/* zero size of converted blob */
	dst.len = 0;

	/* zero size of IV */
	iv.ptr = iv_buf;
	iv.len = 0;

	pem_init_logger();

	while (fetchline(&src, &line))
	{
		if (state == PEM_PRE)
		{
			if (find_boundary("BEGIN", &line))
			{
				state = PEM_MSG;
			}
			continue;
		}
		else
		{
			if (find_boundary("END", &line))
			{
				state = PEM_POST;
				break;
			}
			if (state == PEM_MSG)
			{
				state = (memchr(line.ptr, ':', line.len) == NULL) ? PEM_BODY : PEM_HEADER;
			}
			if (state == PEM_HEADER)
			{
				err_t ugh = NULL;
				chunk_t name  = CHUNK_INITIALIZER;
				chunk_t value = CHUNK_INITIALIZER;

				/* an empty line separates HEADER and BODY */
				if (line.len == 0)
				{
					state = PEM_BODY;
					continue;
				}

				/* we are looking for a parameter: value pair */
				logger->log(logger, CONTROL|LEVEL2, "  %.*s", (int)line.len, line.ptr);
				ugh = extract_parameter_value(&name, &value, &line);
				if (ugh != NULL)
					continue;

				if (match("Proc-Type", &name) && *value.ptr == '4')
					encrypted = TRUE;
				else if (match("DEK-Info", &name))
				{
					size_t len = 0;
					chunk_t dek;

					if (!extract_token(&dek, ',', &value))
						dek = value;

					/* we support DES-EDE3-CBC encrypted files, only */
					if (match("DES-EDE3-CBC", &dek))
					{
						alg = ENCR_3DES;
						key_size = 24;
					}
					else if (match("AES-128-CBC", &dek))
					{
						alg = ENCR_AES_CBC;
						key_size = 16;
					}
					else if (match("AES-192-CBC", &dek))
					{
						alg = ENCR_AES_CBC;
						key_size = 24;
					}
					else if (match("AES-256-CBC", &dek))
					{
						alg = ENCR_AES_CBC;
						key_size = 32;
					}
					else
					{
						return "encryption algorithm not supported";
					}

					eat_whitespace(&value);
					ugh = ttodata(value.ptr, value.len, 16, iv.ptr, 16, &len);
					if (ugh)
						return "error in IV";

					iv.len = len;
				}
			}
			else /* state is PEM_BODY */
			{
				const char *ugh = NULL;
				size_t len = 0;
				chunk_t data;
				
				/* remove any trailing whitespace */
				if (!extract_token(&data ,' ', &line))
				{
					data = line;
				}
				
				/* check for PGP armor checksum */
				if (*data.ptr == '=')
				{
					*pgp = TRUE;
					data.ptr++;
					data.len--;
					logger->log(logger, CONTROL|LEVEL2, "  Armor checksum: %.*s",
								(int)data.len, data.ptr);
		    		continue;
				}

				ugh = ttodata(data.ptr, data.len, 64, dst.ptr, blob->len - dst.len, &len);
				if (ugh)
				{
					state = PEM_ABORT;
					break;
				}
				else
				{
					dst.ptr += len;
					dst.len += len;
				}
			}
		}
	}
	/* set length to size of binary blob */
	blob->len = dst.len;

	if (state != PEM_POST)
		return "file coded in unknown format, discarded";

	return (encrypted)? pem_decrypt(blob, alg, key_size, &iv, passphrase) : NULL;
}
Esempio n. 26
0
void network_process_ignetpush(SpoolControl *sc, struct CtdlMessage *omsg, long *delete_after_send)
{
	StrBuf *Recipient;
	StrBuf *RemoteRoom;
	const char *Pos = NULL;
	struct CtdlMessage *msg = NULL;
	struct CitContext *CCC = CC;
	struct ser_ret sermsg;
	char buf[SIZ];
	char filename[PATH_MAX];
	FILE *fp;
	StrBuf *Buf = NULL;
	int i;
	int bang = 0;
	int send = 1;

	if (sc->Users[ignet_push_share] == NULL)
		return;

	/*
	 * Process IGnet push shares
	 */
	msg = CM_Duplicate(omsg);

	/* Prepend our node name to the Path field whenever
	 * sending a message to another IGnet node
	 */
	Netmap_AddMe(msg, HKEY("username"));

	/*
	 * Determine if this message is set to be deleted
	 * after sending out on the network
	 */
	if (!CM_IsEmpty(msg, eSpecialField)) {
		if (!strcasecmp(msg->cm_fields[eSpecialField], "CANCEL")) {
			*delete_after_send = 1;
		}
	}

	/* Now send it to every node */
	Recipient = NewStrBufPlain(NULL, StrLength(sc->Users[ignet_push_share]));
	RemoteRoom = NewStrBufPlain(NULL, StrLength(sc->Users[ignet_push_share]));
	while ((Pos != StrBufNOTNULL) &&
	       StrBufExtract_NextToken(Recipient, sc->Users[ignet_push_share], &Pos, ','))
	{
		StrBufExtract_NextToken(RemoteRoom, sc->Users[ignet_push_share], &Pos, ',');
		send = 1;
		NewStrBufDupAppendFlush(&Buf, Recipient, NULL, 1);
			
		/* Check for valid node name */
		if (CtdlIsValidNode(NULL,
				    NULL,
				    Buf,
				    sc->working_ignetcfg,
				    sc->the_netmap) != 0)
		{
			QN_syslog(LOG_ERR,
				  "Invalid node <%s>\n",
				  ChrPtr(Recipient));
			
			send = 0;
		}
		
		/* Check for split horizon */
		QN_syslog(LOG_DEBUG, "Path is %s\n", msg->cm_fields[eMessagePath]);
		bang = num_tokens(msg->cm_fields[eMessagePath], '!');
		if (bang > 1) {
			for (i=0; i<(bang-1); ++i) {
				extract_token(buf,
					      msg->cm_fields[eMessagePath],
					      i, '!',
					      sizeof buf);

				QN_syslog(LOG_DEBUG, "Compare <%s> to <%s>\n",
					  buf, ChrPtr(Recipient)) ;
				if (!strcasecmp(buf, ChrPtr(Recipient))) {
					send = 0;
					break;
				}
			}
			
			QN_syslog(LOG_INFO,
				  " %sSending to %s\n",
				  (send)?"":"Not ",
				  ChrPtr(Recipient));
		}
		
		/* Send the message */
		if (send == 1)
		{
			/*
			 * Force the message to appear in the correct
			 * room on the far end by setting the C field
			 * correctly
			 */
			if (StrLength(RemoteRoom) > 0) {
				CM_SetField(msg, eRemoteRoom, SKEY(RemoteRoom));
			}
			else {
				CM_SetField(msg, eRemoteRoom, CCC->room.QRname, strlen(CCC->room.QRname));
			}
			
			/* serialize it for transmission */
			CtdlSerializeMessage(&sermsg, msg);
			if (sermsg.len > 0) {
				
				/* write it to a spool file */
				snprintf(filename,
					 sizeof(filename),
					 "%s/%s@%lx%x",
					 ctdl_netout_dir,
					 ChrPtr(Recipient),
					 time(NULL),
					 rand()
					);
					
				QN_syslog(LOG_DEBUG,
					  "Appending to %s\n",
					  filename);
				
				fp = fopen(filename, "ab");
				if (fp != NULL) {
					fwrite(sermsg.ser,
					       sermsg.len, 1, fp);
					fclose(fp);
				}
				else {
					QN_syslog(LOG_ERR,
						  "%s: %s\n",
						  filename,
						  strerror(errno));
				}

				/* free the serialized version */
				free(sermsg.ser);
			}
		}
	}
	FreeStrBuf(&Buf);
	FreeStrBuf(&Recipient);
	FreeStrBuf(&RemoteRoom);
	CM_Free(msg);
}
Esempio n. 27
0
/* Creates and adds Media-Sub-Components to AVP_LIST
 * @param list - pointer to the AVP_LIST
 * @param sdpA - the SDP body of the INVITE
 * @param sdpB - the SDP body of the 200 OK answer for the INVITE
 * @param number - the number of the media component to use (which m= line?)
 * @param media_sub_component -  array of Gq_Media_Sub_Components elements of type *AAA_AVP that were added
 * @param tag - 0 originating side 1 terminating side 
 * returns the number of media_sub_components added on success -1 on error
 * the media_sub_component is given in order to free the AVPS after grouping them!
 */
inline int Gq_create_add_media_subcomponents(AAA_AVP_LIST *list,str sdpA,str sdpB,int number,AAA_AVP **media_sub_component,int tag)
 {

 	
 
	
	char *mlineA,*mlineB,*clineA,*clineB;
 	char portA[Gq_MAX_Char],portB[Gq_MAX_Char];
 	int intportA,intportB;
 	char addressA[Gq_MAX_Char];
 	char addressB[Gq_MAX_Char];
 	int i=0,flows=0;
 	int atributes=0; /* a= lines present?*/
 	char *newline,*rtp;
	int ports=1; /*how many ports does this m line define?*/
		
 		
 		if (!extract_mclines(sdpA,sdpB,&mlineA,&clineA,&mlineB,&clineB,number))
 		{
 			return -1;
 		}
 		   
 		   /*a= lines are also needed*/
 		 
 		 
 		 if (tag==0) {
 		 	atributes=check_atributes(sdpA,mlineA);
 			
 			
 		 } else {
 		 	atributes=check_atributes(sdpB,mlineB);
 		 	
 		 }
 		 
 		  /*1 means sendonly*/
 		  /*2 means recvonly*/
 		  /*0 is no a= line or sendrecv or recvonly*/
 		 	
 		
 		 
 		if (!extract_token(mlineA,portA,Gq_MAX_Char,2))
 		{
 				return -1; /*problem extracting port*/
 		}
 		if (!extract_token(mlineB,portB,Gq_MAX_Char,2))
 		{
 				return -1; /* either no ' ' or Gq_MAX_Char too small*/
 		}
 		
 		/*check if this are ports or multiports!*/
 		
 		if(!is_a_port(portA) || !is_a_port(portB)) 
 		{
 			return -1; /* there was a word there but it isn't a port*/
 		}
 		 		 		
 		if (strncmp(portA,"0",1)!=0 && strncmp(portB,"0",1)==0)
 		{
 			/*this means answerer rejected the offer*/
 			
 			return 0; /*this is more logical*/
 		}
 		
 		/*the next lines have nothing to do with rtp
 		 * i just reused the pointer*/	
 		rtp=index(portA,'/');
 		if (rtp!=NULL)
 		{
 			sscanf(portA,"%*i/%i%*s",&ports);
 			*rtp='\0'; 
 				
 		}	
 		
 		 		
 		
 		if(!extract_token(clineA,addressA,Gq_MAX_Char,3))
 		{
 			return -1;
 		}
 		if(!extract_token(clineB,addressB,Gq_MAX_Char,3))
 		{
 			return -1;
 		}
 		
 		
				
				
 		/* i is the flow number */
 		/*flows is the number of data flows .. for each port 1 data flow*/
 			
 			while(flows<ports && i+2<Gq_Media_Sub_Components)
 			{
 				
 				i++;
 				if (tag!=1)
 				{
 					media_sub_component[i-1]=Gq_create_media_subcomponent(i,"ip",addressA,portA,addressB,portB,"",atributes);
 					AAAAddAVPToAVPList(list,media_sub_component[i-1]);		
 				} else {
 		
 					media_sub_component[i-1]=Gq_create_media_subcomponent(i,"ip",addressB,portB,addressA,portA,"",atributes);
 					AAAAddAVPToAVPList(list,media_sub_component[i-1]);		
 				}
 				flows++;
 			
 				if (1) 
 				{
		 			rtp=strstr(mlineA,"RTP");
		 			newline=index(mlineA,'\n');
		 	
		 			if (rtp!=NULL && rtp < newline)
		 	 		{
		 			i++;
		 			/*please optimize here!*/
		 				sscanf(portA,"%i",&intportA);
		 				sscanf(portB,"%i",&intportB);
		 				intportA++; 
		 				intportB++;
		 				sprintf(portA,"%i",intportA);
		 				sprintf(portB,"%i",intportB);
		 				if (tag!=1)
		 				{
		 					media_sub_component[i-1]=Gq_create_media_subcomponent(i,"ip",addressA,portA,addressB,portB,"",3);
		 					AAAAddAVPToAVPList(list,media_sub_component[i-1]);	
		 				} else {
		 					media_sub_component[i-1]=Gq_create_media_subcomponent(i,"ip",addressB,portB,addressA,portA,"",3);
		 					AAAAddAVPToAVPList(list,media_sub_component[i-1]);	
		 				}		 		
		 			}
	 				sscanf(portA,"%i",&intportA);
	 				sscanf(portB,"%i",&intportB);
	 				intportA++;  
		 			intportB++;
		 			sprintf(portA,"%i",intportA);
		 			sprintf(portB,"%i",intportB);
		 			
		 			/*if its not an RTP flow and it has multiports then the odd ports
		 			 * are used for the next component .. if it is RTP and multiports than 
		 			 * the even ports are for the next component because the odd are used for 
		 			 * RTCP flows*/
 				}						
 											
 			}							
 	  	
 	return (i);
 }
/**
 * load IMCs from a configuration file
 */
static bool load_imcs(char *filename)
{
	int fd, line_nr = 0;
	chunk_t src, line;
	struct stat sb;
	void *addr;

	DBG1(DBG_TNC, "loading IMCs from '%s'", filename);
	fd = open(filename, O_RDONLY);
	if (fd == -1)
	{
		DBG1(DBG_TNC, "opening configuration file '%s' failed: %s", filename,
			 strerror(errno));
		return FALSE;
	}
	if (fstat(fd, &sb) == -1)
	{
		DBG1(DBG_LIB, "getting file size of '%s' failed: %s", filename,
			 strerror(errno));
		close(fd);
		return FALSE;
	}
	addr = mmap(NULL, sb.st_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
	if (addr == MAP_FAILED)
	{
		DBG1(DBG_LIB, "mapping '%s' failed: %s", filename, strerror(errno));
		close(fd);
		return FALSE;
	}
	src = chunk_create(addr, sb.st_size);

	while (fetchline(&src, &line))
	{
		char *name, *path;
		chunk_t token;
		imc_t *imc;

		line_nr++;

		/* skip comments or empty lines */
		if (*line.ptr == '#' || !eat_whitespace(&line))
		{
			continue;
		}

		/* determine keyword */
		if (!extract_token(&token, ' ', &line))
		{
			DBG1(DBG_TNC, "line %d: keyword must be followed by a space",
						   line_nr);
			return FALSE;
		}

		/* only interested in IMCs */
		if (!match("IMC", &token))
		{
			continue;
		}

		/* advance to the IMC name and extract it */
		if (!extract_token(&token, '"', &line) ||
			!extract_token(&token, '"', &line))
		{
			DBG1(DBG_TNC, "line %d: IMC name must be set in double quotes",
						   line_nr);
			return FALSE;
		}

		/* copy the IMC name */
		name = malloc(token.len + 1);
		memcpy(name, token.ptr, token.len);
		name[token.len] = '\0';

		/* advance to the IMC path and extract it */
		if (!eat_whitespace(&line))
		{
			DBG1(DBG_TNC, "line %d: IMC path is missing", line_nr);
			free(name);
			return FALSE;
		}
		if (!extract_token(&token, ' ', &line))
		{
			token = line;
		}

		/* copy the IMC path */
		path = malloc(token.len + 1);
		memcpy(path, token.ptr, token.len);
		path[token.len] = '\0';

		/* load and register IMC instance */
		imc = tnc_imc_create(name, path);
		if (!imc)
		{
			free(name);
			free(path);
			return FALSE;
		}
		if (!charon->imcs->add(charon->imcs, imc))
		{
			if (imc->terminate &&
				imc->terminate(imc->get_id(imc)) != TNC_RESULT_SUCCESS)
			{
				DBG1(DBG_TNC, "IMC \"%s\" not terminated successfully",
							   imc->get_name(imc));
			}
			imc->destroy(imc);
			return FALSE;
		}
		DBG1(DBG_TNC, "IMC %u \"%s\" loaded from '%s'", imc->get_id(imc),
														name, path);
	}
	munmap(addr, sb.st_size);
	close(fd);
	return TRUE;
}
Esempio n. 29
0
// ----------------------------------------------------------------------------
//
std::vector<CString> SimpleJsonParser::tokenize( LPCSTR value, LPCSTR break_chars, bool store_breaks ) 
{
    std::vector<CString> tokens;

    LPCSTR start;
    LPCSTR head;
    CString token;

    bool in_quotes = false;
    bool in_token = false;
    bool must_break = false;

    char last_char = '\0';

    for ( head=start=value; *head; head++ ) {
        if ( in_quotes ) {
            if ( *head == '"' && last_char != '\\' ) {
                in_quotes = false;
                must_break = true;
                token = extract_token( start, head );
            }
        }
        else if ( iswspace(*head) ) {
            if ( in_token && !must_break ) {
                token = extract_token( start, head-1 );
                must_break = true;
            } 
            else if ( !in_token )
                start = head+1;
            else
                ; // Ignore WS between tokens and breaks
        }
        else if ( strchr( break_chars, *head ) != NULL ) {
            if ( in_token && !must_break )  // Non-quoted literal
                token = extract_token( start, head-1 );

            if ( in_token )
                tokens.push_back( token );

            if ( store_breaks )
                tokens.push_back( extract_token( head, head ) );

            start = head+1;
            in_token = must_break = false;
        }
        else if ( must_break )
            throw std::exception( "Parse error" );
        else {
            in_token = true;
            
            if ( *head == '"'  && last_char != '\\' )
                in_quotes = true;
        }

        last_char = *head;
    }
    
    if ( in_token ) {
        if ( in_quotes )
            throw std::exception( "Unterminate quotes" );

        if ( !must_break )      // Non-quoted literal
            token = extract_token( start, head-1 );

        tokens.push_back( token );
    }

    return tokens;
}
// ----------------------------------------------------------------------------
//
void SimpleJsonTokenizer::advanceToken() {
	bool in_quotes = false;

	while ( !m_token_available && !m_break_available && *m_head ) {
		if ( in_quotes ) {
			if ( *m_head == '"' && m_last_char != '\\' ) {
				in_quotes = false;
				m_must_break = true;
				extract_token( m_start, m_head );
			}
		}
		else if ( iswspace(*m_head) ) {
			if ( m_in_token && !m_must_break ) {
				extract_token( m_start, m_head-1 );
				m_must_break = true;
			} 
			else if ( !m_in_token )
				m_start = m_head+1;
			else
				; // Ignore WS between tokens and breaks
		}
		else if ( strchr( m_break_chars, *m_head ) != NULL ) {
			if ( m_in_token && !m_must_break )  // Non-quoted literal
				extract_token( m_start, m_head-1 );

			if ( m_in_token )
				m_token_available = true;

			if ( m_store_breaks ) {
				m_break_char = *m_head;
				m_break_available = true;
			}

			m_start = m_head+1;
			m_in_token = m_must_break = false;
		}
		else if ( m_must_break )
			throw std::exception( "Parse error" );
		else {
			m_in_token = true;

			if ( *m_head == '"'  && m_last_char != '\\' )
				in_quotes = true;
		}

		m_last_char = *m_head;

		m_head++;
	}

	if ( m_token_available || m_break_available )
		return;

	if ( m_in_token ) {
		if ( in_quotes )
			throw std::exception( "Unterminate quotes" );

		if ( !m_must_break )  // Non-quoted literal
			extract_token( m_start, m_head-1 );

		m_token_available = true;
		m_in_token = false;
	}
}