예제 #1
0
static void StrBufRFC2047encodeMessageStdin(void)
{
	int fdin = 0;// STDIN
	const char *Err;
	StrBuf *Target;
	StrBuf *Source;
	StrBuf *Src;

	Source = NewStrBuf();
	Src = NewStrBuf();

	printf("[");
	while (fdin == 0) {

		StrBufTCP_read_line(Source, &fdin, 0, &Err);
		StrBufAppendBuf(Src, Source, 0);
		StrBufAppendBufPlain(Src, HKEY("\n"), 0);
				
	}

	Target = StrBufRFC2047encodeMessage(Src);

	printf("Target: \n%s\n", ChrPtr(Target));
	FreeStrBuf(&Source);
	FreeStrBuf(&Src);
	FreeStrBuf(&Target);
}
예제 #2
0
void Header_HandleHost(StrBuf *Line, ParsedHttpHdrs *hdr)
{
	if (hdr->HostHeader != NULL) {
		FreeStrBuf(&hdr->HostHeader);
	}
	hdr->HostHeader = NewStrBuf();
	StrBufAppendPrintf(hdr->HostHeader, "%s://", (is_https ? "https" : "http") );
	StrBufAppendBuf(hdr->HostHeader, Line, 0);
}
예제 #3
0
/*
 * Look for URL's embedded in a buffer and make them linkable.  We use a
 * target window in order to keep the Citadel session in its own window.
 */
void UrlizeText(StrBuf* Target, StrBuf *Source, StrBuf *WrkBuf)
{
	int len, UrlLen, Offset, TrailerLen;
	const char *start, *end, *pos;
	
	FlushStrBuf(Target);

	start = NULL;
	len = StrLength(Source);
	end = ChrPtr(Source) + len;
	for (pos = ChrPtr(Source); (pos < end) && (start == NULL); ++pos) {
		if (!strncasecmp(pos, "http://", 7))
			start = pos;
		else if (!strncasecmp(pos, "ftp://", 6))
			start = pos;
	}

	if (start == NULL) {
		StrBufAppendBuf(Target, Source, 0);
		return;
	}
	FlushStrBuf(WrkBuf);

	for (pos = ChrPtr(Source) + len; pos > start; --pos) {
		if (  (!isprint(*pos))
		   || (isspace(*pos))
		   || (*pos == '{')
		   || (*pos == '}')
		   || (*pos == '|')
		   || (*pos == '\\')
		   || (*pos == '^')
		   || (*pos == '[')
		   || (*pos == ']')
		   || (*pos == '`')
		   || (*pos == '<')
		   || (*pos == '>')
		   || (*pos == '(')
		   || (*pos == ')')
		) {
			end = pos;
		}
	}
	
	UrlLen = end - start;
	StrBufAppendBufPlain(WrkBuf, start, UrlLen, 0);

	Offset = start - ChrPtr(Source);
	if (Offset != 0)
		StrBufAppendBufPlain(Target, ChrPtr(Source), Offset, 0);
	StrBufAppendPrintf(Target, "%ca href=%c%s%c TARGET=%c%s%c%c%s%c/A%c",
			   LB, QU, ChrPtr(WrkBuf), QU, QU, TARGET, 
			   QU, RB, ChrPtr(WrkBuf), LB, RB);

	TrailerLen = StrLength(Source) - (end - ChrPtr(Source));
	if (TrailerLen > 0)
		StrBufAppendBufPlain(Target, end, TrailerLen, 0);
}
예제 #4
0
void xrds_xml_end(void *data, const char *supplied_el) {
	struct xrds *xrds = (struct xrds *) data;

	--xrds->nesting_level;

	if (!strcasecmp(supplied_el, "XRD")) {
		--xrds->in_xrd;
	}

	else if (!strcasecmp(supplied_el, "type")) {
		if (	(xrds->in_xrd)
			&& (!strcasecmp(ChrPtr(xrds->CharData), "http://specs.openid.net/auth/2.0/server"))
		) {
			xrds->current_service_is_oid2auth = 1;
		}
		if (	(xrds->in_xrd)
			&& (!strcasecmp(ChrPtr(xrds->CharData), "http://specs.openid.net/auth/2.0/signon"))
		) {
			xrds->current_service_is_oid2auth = 1;
			/* FIXME in this case, the Claimed ID should be considered immutable */
		}
	}

	else if (!strcasecmp(supplied_el, "uri")) {
		if (xrds->in_xrd) {
			FlushStrBuf(xrds->current_service_uri);
			StrBufAppendBuf(xrds->current_service_uri, xrds->CharData, 0);
		}
	}

	else if (!strcasecmp(supplied_el, "service")) {
		if (	(xrds->in_xrd)
			&& (xrds->current_service_priority < xrds->selected_service_priority)
			&& (xrds->current_service_is_oid2auth)
		) {
			xrds->selected_service_priority = xrds->current_service_priority;
			FlushStrBuf(xrds->selected_service_uri);
			StrBufAppendBuf(xrds->selected_service_uri, xrds->current_service_uri, 0);
		}

	}

	FlushStrBuf(xrds->CharData);
}
예제 #5
0
void aggregate_recipients(StrBuf **recps, RoomNetCfg Which, OneRoomNetCfg *OneRNCfg, long nSegments)
{
	int i;
	size_t recps_len = 0;
	RoomNetCfgLine *nptr;
	struct CitContext *CCC = CC;

	*recps = NULL;
	/*
	 * Figure out how big a buffer we need to allocate
	 */
	for (nptr = OneRNCfg->NetConfigs[Which]; nptr != NULL; nptr = nptr->next) {
		recps_len = recps_len + StrLength(nptr->Value[0]) + 2;
	}

	/* Nothing todo... */
	if (recps_len == 0)
		return;

	*recps = NewStrBufPlain(NULL, recps_len);

	if (*recps == NULL) {
		QN_syslog(LOG_EMERG,
			  "Cannot allocate %ld bytes for recps...\n",
			  (long)recps_len);
		abort();
	}

	/* Each recipient */
	for (nptr = OneRNCfg->NetConfigs[Which]; nptr != NULL; nptr = nptr->next) {
		if (nptr != OneRNCfg->NetConfigs[Which]) {
			for (i = 0; i < nSegments; i++)
				StrBufAppendBufPlain(*recps, HKEY(","), i);
		}
		StrBufAppendBuf(*recps, nptr->Value[0], 0);
		if (Which == ignet_push_share)
		{
			StrBufAppendBufPlain(*recps, HKEY(","), 0);
			StrBufAppendBuf(*recps, nptr->Value[1], 0);

		}
	}
}
예제 #6
0
void Header_HandleXFFHost(StrBuf *Line, ParsedHttpHdrs *hdr)
{
	if (!follow_xff) return;

	if (hdr->HostHeader != NULL) {
		FreeStrBuf(&hdr->HostHeader);
	}

	hdr->HostHeader = NewStrBuf();
	StrBufAppendPrintf(hdr->HostHeader, "http://");	/* this is naive; do something about it */
	StrBufAppendBuf(hdr->HostHeader, Line, 0);
}
예제 #7
0
static void CreateWildfireSampleMessage(StrBuf *OutBuf)
{
	JsonValue *Error;
		
	StrBuf *Buf;
	StrBuf *Header;
	StrBuf *Json;
	int n = 1;

	Header = NewStrBuf();
	Json = NewStrBuf();

	Error = WildFireMessagePlain(HKEY(__FILE__), __LINE__, HKEY("Info message"), eINFO);
	SerializeJson(Json, Error, 1);
	WildFireSerializePayload(Json, Header, &n, NULL);
	StrBufAppendBuf(OutBuf, Header, 0);
	FlushStrBuf(Json);
	FlushStrBuf(Header);

	Error = WildFireMessagePlain(HKEY(__FILE__), __LINE__,  HKEY("Warn message"), eWARN);
	SerializeJson(Json, Error, 1);
	WildFireSerializePayload(Json, Header, &n, NULL);
	StrBufAppendBuf(OutBuf, Header, 0);
	FlushStrBuf(Json);
	FlushStrBuf(Header);

	Error = WildFireMessagePlain(HKEY(__FILE__), __LINE__, HKEY("Error message"), eERROR);
	SerializeJson(Json, Error, 1);
	WildFireSerializePayload(Json, Header, &n, NULL);
	StrBufAppendBuf(OutBuf, Header, 0);
	FlushStrBuf(Json);
	FlushStrBuf(Header);

	Error = WildFireMessagePlain(HKEY(__FILE__), __LINE__, HKEY("Info message"), eINFO);
	SerializeJson(Json, Error, 1);
	WildFireSerializePayload(Json, Header, &n, NULL);
	StrBufAppendBuf(OutBuf, Header, 0);
	FlushStrBuf(Json);
	FlushStrBuf(Header);

	Error = WildFireMessagePlain(HKEY(__FILE__), __LINE__, HKEY("Info message"), eINFO);
	SerializeJson(Json, Error, 1);
	WildFireSerializePayload(Json, Header, &n, NULL);
	StrBufAppendBuf(OutBuf, Header, 0);
	FlushStrBuf(Json);
	FlushStrBuf(Header);


	Buf = NewStrBufPlain(HKEY("test error message"));
	Error = WildFireException(HKEY(__FILE__), __LINE__, Buf, 1);
	SerializeJson(Json, Error, 1);
	WildFireSerializePayload(Json, Header, &n, NULL);
	StrBufAppendBuf(OutBuf, Header, 0);

	FreeStrBuf(&Buf);
	FreeStrBuf(&Json);
	FreeStrBuf(&Header);

}
예제 #8
0
StrBuf *SerializeQueueItem(OneQueItem *MyQItem)
{
	StrBuf *QMessage;
	HashPos  *It;
	const char *Key;
	long len;
	void *vQE;

	QMessage = NewStrBufPlain(NULL, SIZ);
	StrBufPrintf(QMessage, "Content-type: %s\n", SPOOLMIME);
//	"attempted|%ld\n"  "retry|%ld\n",, (long)time(NULL), (long)retry );
	StrBufAppendBufPlain(QMessage, HKEY("\nmsgid|"), 0);
	StrBufAppendPrintf(QMessage, "%ld", MyQItem->MessageID);

	StrBufAppendBufPlain(QMessage, HKEY("\nsubmitted|"), 0);
	StrBufAppendPrintf(QMessage, "%ld", MyQItem->Submitted);

	if (StrLength(MyQItem->BounceTo) > 0) {
		StrBufAppendBufPlain(QMessage, HKEY("\nbounceto|"), 0);
		StrBufAppendBuf(QMessage, MyQItem->BounceTo, 0);
	}

	if (StrLength(MyQItem->EnvelopeFrom) > 0) {
		StrBufAppendBufPlain(QMessage, HKEY("\nenvelope_from|"), 0);
		StrBufAppendBuf(QMessage, MyQItem->EnvelopeFrom, 0);
	}

	if (StrLength(MyQItem->SenderRoom) > 0) {
		StrBufAppendBufPlain(QMessage, HKEY("\nsource_room|"), 0);
		StrBufAppendBuf(QMessage, MyQItem->SenderRoom, 0);
	}

	StrBufAppendBufPlain(QMessage, HKEY("\nretry|"), 0);
	StrBufAppendPrintf(QMessage, "%ld",
			   MyQItem->Retry);

	StrBufAppendBufPlain(QMessage, HKEY("\nattempted|"), 0);
	StrBufAppendPrintf(QMessage, "%ld",
			   time(NULL) /*ctdl_ev_now()*/ + MyQItem->Retry);

	It = GetNewHashPos(MyQItem->MailQEntries, 0);
	while (GetNextHashPos(MyQItem->MailQEntries, It, &len, &Key, &vQE))
	{
		MailQEntry *ThisItem = vQE;

		StrBufAppendBufPlain(QMessage, HKEY("\nremote|"), 0);
		StrBufAppendBuf(QMessage, ThisItem->Recipient, 0);
		StrBufAppendBufPlain(QMessage, HKEY("|"), 0);
		StrBufAppendPrintf(QMessage, "%d", ThisItem->Status);
		StrBufAppendBufPlain(QMessage, HKEY("|"), 0);
		if (ThisItem->AllStatusMessages != NULL)
			StrBufAppendBuf(QMessage, ThisItem->AllStatusMessages, 0);
		else
			StrBufAppendBuf(QMessage, ThisItem->StatusMessage, 0);
	}
	DeleteHashPos(&It);
	StrBufAppendBufPlain(QMessage, HKEY("\n"), 0);
	return QMessage;
}
예제 #9
0
/*
 * Offer the RSS feed button for this room
 */
void tmplput_rssbutton(StrBuf *Target, WCTemplputParams *TP) 
{
	StrBuf *FeedLink = NULL;

	FeedLink = NewStrBufPlain(HKEY("/feed_rss?go="));
	StrBufUrlescAppend(FeedLink, WC->CurRoom.name, NULL);

	StrBufAppendPrintf(Target, "<a type=\"application/rss+xml\" href=\"");
	StrBufAppendBuf(Target, FeedLink, 0);
	StrBufAppendPrintf(Target, "\"><img src=\"static/webcit_icons/essen/16x16/rss.png\" alt=\"RSS\">");
	StrBufAppendPrintf(Target, "</a>");
	FreeStrBuf(&FeedLink);
}
예제 #10
0
eNextState FailOneAttempt(AsyncIO *IO)
{
	SmtpOutMsg *Msg = IO->Data;

	SetSMTPState(IO, eSTMPfailOne);
	if (Msg->MyQEntry->Status == 2)
		return eAbort;

	/*
	 * possible ways here:
	 * - connection timeout
	 * - dns lookup failed
	 */
	StopClientWatchers(IO, 1);

	Msg->MyQEntry->nAttempt ++;
	if (Msg->MyQEntry->AllStatusMessages == NULL)
		Msg->MyQEntry->AllStatusMessages = NewStrBuf();

	StrBufAppendPrintf(Msg->MyQEntry->AllStatusMessages, "%ld) ", Msg->MyQEntry->nAttempt);
	StrBufAppendBuf(Msg->MyQEntry->AllStatusMessages, Msg->MyQEntry->StatusMessage, 0);
	StrBufAppendBufPlain(Msg->MyQEntry->AllStatusMessages, HKEY("; "), 0);

	if (Msg->pCurrRelay != NULL)
		Msg->pCurrRelay = Msg->pCurrRelay->Next;
	if ((Msg->pCurrRelay != NULL) &&
	    !Msg->pCurrRelay->IsRelay &&
	    Msg->MyQItem->HaveRelay)
	{
		EVS_syslog(LOG_DEBUG, "%s Aborting; last relay failed.\n", __FUNCTION__);
		return FinalizeMessageSend(Msg);
	}

	if (Msg->pCurrRelay == NULL) {
		EVS_syslog(LOG_DEBUG, "%s Aborting\n", __FUNCTION__);
		return FinalizeMessageSend(Msg);
	}
	if (Msg->pCurrRelay->IsIP) {
		EVS_syslog(LOG_DEBUG, "%s connecting IP\n", __FUNCTION__);
		return mx_connect_ip(IO);
	}
	else {
		EVS_syslog(LOG_DEBUG,
			   "%s resolving next MX Record\n",
			   __FUNCTION__);
		return get_one_mx_host_ip(IO);
	}
}
예제 #11
0
static void ListCalculateSubject(struct CtdlMessage *msg)
{
	struct CitContext *CCC = CC;
	StrBuf *Subject, *FlatSubject;
	int rlen;
	char *pCh;

	if (CM_IsEmpty(msg, eMsgSubject)) {
		Subject = NewStrBufPlain(HKEY("(no subject)"));
	}
	else {
		Subject = NewStrBufPlain(CM_KEY(msg, eMsgSubject));
	}
	FlatSubject = NewStrBufPlain(NULL, StrLength(Subject));
	StrBuf_RFC822_to_Utf8(FlatSubject, Subject, NULL, NULL);

	rlen = strlen(CCC->room.QRname);
	pCh  = strstr(ChrPtr(FlatSubject), CCC->room.QRname);
	if ((pCh == NULL) ||
	    (*(pCh + rlen) != ']') ||
	    (pCh == ChrPtr(FlatSubject)) ||
	    (*(pCh - 1) != '[')
		)
	{
		StrBuf *tmp;
		StrBufPlain(Subject, HKEY("["));
		StrBufAppendBufPlain(Subject,
				     CCC->room.QRname,
				     rlen, 0);
		StrBufAppendBufPlain(Subject, HKEY("] "), 0);
		StrBufAppendBuf(Subject, FlatSubject, 0);
		/* so we can free the right one swap them */
		tmp = Subject;
		Subject = FlatSubject;
		FlatSubject = tmp;
		StrBufRFC2047encode(&Subject, FlatSubject);
	}

	CM_SetAsFieldSB(msg, eMsgSubject, &Subject);

	FreeStrBuf(&FlatSubject);
}
예제 #12
0
/*
 * Parse an XRDS document.
 * If an OpenID Provider URL is discovered, op_url to that value and return nonzero.
 * If nothing useful happened, return 0.
 */
int parse_xrds_document(StrBuf *ReplyBuf) {
	ctdl_openid *oiddata = (ctdl_openid *) CC->openid_data;
	struct xrds xrds;
	int return_value = 0;

	memset(&xrds, 0, sizeof (struct xrds));
	xrds.selected_service_priority = INT_MAX;
	xrds.CharData = NewStrBuf();
	xrds.current_service_uri = NewStrBuf();
	xrds.selected_service_uri = NewStrBuf();
	XML_Parser xp = XML_ParserCreate(NULL);
	if (xp) {
		XML_SetUserData(xp, &xrds);
		XML_SetElementHandler(xp, xrds_xml_start, xrds_xml_end);
		XML_SetCharacterDataHandler(xp, xrds_xml_chardata);
		XML_Parse(xp, ChrPtr(ReplyBuf), StrLength(ReplyBuf), 0);
		XML_Parse(xp, "", 0, 1);
		XML_ParserFree(xp);
	}
	else {
		syslog(LOG_ALERT, "Cannot create XML parser");
	}

	if (xrds.selected_service_priority < INT_MAX) {
		if (oiddata->op_url == NULL) {
			oiddata->op_url = NewStrBuf();
		}
		FlushStrBuf(oiddata->op_url);
		StrBufAppendBuf(oiddata->op_url, xrds.selected_service_uri, 0);
		return_value = openid_disco_xrds;
	}

	FreeStrBuf(&xrds.CharData);
	FreeStrBuf(&xrds.current_service_uri);
	FreeStrBuf(&xrds.selected_service_uri);

	return(return_value);
}
예제 #13
0
/**
 * @brief lineread Handler;
 * understands when to read more SMTP lines, and when this is a one-lined reply.
 */
eReadState SMTP_C_ReadServerStatus(AsyncIO *IO)
{
	eReadState Finished = eBufferNotEmpty;

	while (Finished == eBufferNotEmpty) {
		Finished = StrBufChunkSipLine(IO->IOBuf, &IO->RecvBuf);

		switch (Finished) {
		case eMustReadMore: /// read new from socket...
			return Finished;
			break;
		case eBufferNotEmpty: /* shouldn't happen... */
		case eReadSuccess: /// done for now...
			if (StrLength(IO->IOBuf) < 4)
				continue;
			if (ChrPtr(IO->IOBuf)[3] == '-')
			{
				SmtpOutMsg *Msg;
				Msg = (SmtpOutMsg *)IO->Data;
				if (Msg->MultiLineBuf == NULL)
					Msg->MultiLineBuf = NewStrBuf ();
				else
					StrBufAppendBufPlain(Msg->MultiLineBuf, HKEY("\n"), 0);
				StrBufAppendBuf(Msg->MultiLineBuf, IO->IOBuf, 0);
				Finished = eBufferNotEmpty;
			}
			else
				return Finished;
			break;
		case eReadFail: /// WHUT?
			///todo: shut down!
			break;
		}
	}
	return Finished;
}
예제 #14
0
/*
 * This is the back end for flush_conversations_to_disk()
 * At this point we've isolated a single conversation (struct imlog)
 * and are ready to write it to disk.
 */
void flush_individual_conversation(struct imlog *im) {
	struct CtdlMessage *msg;
	long msgnum = 0;
	char roomname[ROOMNAMELEN];
	StrBuf *MsgBuf, *FullMsgBuf;

	StrBufAppendBufPlain(im->conversation, HKEY(
		"</body>\r\n"
		"</html>\r\n"
		), 0
	);

	MsgBuf = StrBufRFC2047encodeMessage(im->conversation);
	FlushStrBuf(im->conversation);
	FullMsgBuf = NewStrBufPlain(NULL, StrLength(im->conversation) + 100);

	StrBufAppendBufPlain(FullMsgBuf, HKEY(
			"Content-type: text/html; charset=UTF-8\r\n"
			"Content-Transfer-Encoding: quoted-printable\r\n"
			"\r\n"
			), 0);
	StrBufAppendBuf (FullMsgBuf, MsgBuf, 0);
	FreeStrBuf(&MsgBuf);

	msg = malloc(sizeof(struct CtdlMessage));
	memset(msg, 0, sizeof(struct CtdlMessage));
	msg->cm_magic = CTDLMESSAGE_MAGIC;
	msg->cm_anon_type = MES_NORMAL;
	msg->cm_format_type = FMT_RFC822;
	if (!IsEmptyStr(im->usernames[0])) {
		CM_SetField(msg, eAuthor, im->usernames[0], strlen(im->usernames[0]));
	} else {
		CM_SetField(msg, eAuthor, HKEY("Citadel"));
	}
	if (!IsEmptyStr(im->usernames[1])) {
		CM_SetField(msg, eRecipient, im->usernames[1], strlen(im->usernames[1]));
	}

	CM_SetField(msg, eOriginalRoom, HKEY(PAGELOGROOM));
	CM_SetField(msg, eNodeName, CFG_KEY(c_nodename));
	CM_SetAsFieldSB(msg, eMesageText, &FullMsgBuf);	/* we own this memory now */

	/* Start with usernums[1] because it's guaranteed to be higher than usernums[0],
	 * so if there's only one party, usernums[0] will be zero but usernums[1] won't.
	 * Create the room if necessary.  Note that we create as a type 5 room rather
	 * than 4, which indicates that it's a personal room but we've already supplied
	 * the namespace prefix.
	 *
	 * In the unlikely event that usernums[1] is zero, a room with an invalid namespace
	 * prefix will be created.  That's ok because the auto-purger will clean it up later.
	 */
	snprintf(roomname, sizeof roomname, "%010ld.%s", im->usernums[1], PAGELOGROOM);
	CtdlCreateRoom(roomname, 5, "", 0, 1, 1, VIEW_BBS);
	msgnum = CtdlSubmitMsg(msg, NULL, roomname, 0);
	CM_Free(msg);

	/* If there is a valid user number in usernums[0], save a copy for them too. */
	if (im->usernums[0] > 0) {
		snprintf(roomname, sizeof roomname, "%010ld.%s", im->usernums[0], PAGELOGROOM);
		CtdlCreateRoom(roomname, 5, "", 0, 1, 1, VIEW_BBS);
		CtdlSaveMsgPointerInRoom(roomname, msgnum, 0, NULL);
	}

	/* Finally, if we're logging instant messages globally, do that now. */
	if (!IsEmptyStr(config.c_logpages)) {
		CtdlCreateRoom(config.c_logpages, 3, "", 0, 1, 1, VIEW_BBS);
		CtdlSaveMsgPointerInRoom(config.c_logpages, msgnum, 0, NULL);
	}

}
예제 #15
0
파일: webcit.c 프로젝트: henri14/citadel
void tmplput_csslocal(StrBuf *Target, WCTemplputParams *TP)
{
	StrBufAppendBuf(Target, 
			csslocal, 0);
}
예제 #16
0
파일: webcit.c 프로젝트: henri14/citadel
/*
 * Wraps a Citadel server command in an AJAX transaction.
 */
void ajax_servcmd(void)
{
	wcsession *WCC = WC;
	int Done = 0;
	StrBuf *Buf;
	char *junk;
	size_t len;

	if (verbose)
		syslog(LOG_DEBUG, "ajax_servcmd() g_cmd=\"%s\"", bstr("g_cmd") );
	begin_ajax_response();
	Buf = NewStrBuf();
	serv_puts(bstr("g_cmd"));
	StrBuf_ServGetln(Buf);
	StrBufAppendBuf(WCC->WBuf, Buf, 0);
	StrBufAppendBufPlain(WCC->WBuf, HKEY("\n"), 0);
	
	switch (GetServerStatus(Buf, NULL)) {
	case 8:
		serv_puts("\n\n000");
		if ( (StrLength(Buf)==3) && 
		     !strcmp(ChrPtr(Buf), "000")) {
			StrBufAppendBufPlain(WCC->WBuf, HKEY("\000"), 0);
			break;
		}
	case 1:
		while (!Done) {
			if (StrBuf_ServGetln(Buf) < 0)
				break;
			if ( (StrLength(Buf)==3) && 
			     !strcmp(ChrPtr(Buf), "000")) {
				Done = 1;
			}
			StrBufAppendBuf(WCC->WBuf, Buf, 0);
			StrBufAppendBufPlain(WCC->WBuf, HKEY("\n"), 0);
		}
		break;
	case 4:
		text_to_server(bstr("g_input"));
		serv_puts("000");
		break;
	case 6:
		len = atol(&ChrPtr(Buf)[4]);
		StrBuf_ServGetBLOBBuffered(Buf, len);
		break;
	case 7:
		len = atol(&ChrPtr(Buf)[4]);
		junk = malloc(len);
		memset(junk, 0, len);
		serv_write(junk, len);
		free(junk);
	}
	
	end_ajax_response();
	
	/*
	 * This is kind of an ugly hack, but this is the only place it can go.
	 * If the command was GEXP, then the instant messenger window must be
	 * running, so reset the "last_pager_check" watchdog timer so
	 * that page_popup() doesn't try to open it a second time. TODO: page_popup isn't with us anymore.
	 */
	if (!strncasecmp(bstr("g_cmd"), "GEXP", 4)) {
		WCC->last_pager_check = time(NULL);
	}
	FreeStrBuf(&Buf);
}
예제 #17
0
/*
 * Scan a room's netconfig to determine whether it requires POP3 aggregation
 */
void pop3client_scan_room(struct ctdlroom *qrbuf, void *data, OneRoomNetCfg *OneRNCFG)
{
	const RoomNetCfgLine *pLine;
	void *vptr;

	pthread_mutex_lock(&POP3QueueMutex);
	if (GetHash(POP3QueueRooms, LKEY(qrbuf->QRnumber), &vptr))
	{
		pthread_mutex_unlock(&POP3QueueMutex);
		EVP3CQ_syslog(LOG_DEBUG,
			      "pop3client: [%ld] %s already in progress.",
			      qrbuf->QRnumber,
			      qrbuf->QRname);
		return;
	}
	pthread_mutex_unlock(&POP3QueueMutex);

	if (server_shutting_down) return;

	pLine = OneRNCFG->NetConfigs[pop3client];

	while (pLine != NULL)
	{
		pop3aggr *cptr;

		cptr = (pop3aggr *) malloc(sizeof(pop3aggr));
		memset(cptr, 0, sizeof(pop3aggr));
		///TODO do we need this? cptr->roomlist_parts=1;
		cptr->RoomName = NewStrBufPlain(qrbuf->QRname, -1);
		cptr->pop3user = NewStrBufDup(pLine->Value[1]);
		cptr->pop3pass = NewStrBufDup(pLine->Value[2]);
		cptr->Url = NewStrBuf();
		cptr->Host = NewStrBufDup(pLine->Value[0]);

		cptr->keep = atol(ChrPtr(pLine->Value[3]));
		cptr->interval = atol(ChrPtr(pLine->Value[4]));

		StrBufAppendBufPlain(cptr->Url, HKEY("pop3://"), 0);
		StrBufUrlescUPAppend(cptr->Url, cptr->pop3user, NULL);
		StrBufAppendBufPlain(cptr->Url, HKEY(":"), 0);
		StrBufUrlescUPAppend(cptr->Url, cptr->pop3pass, NULL);
		StrBufAppendBufPlain(cptr->Url, HKEY("@"), 0);
		StrBufAppendBuf(cptr->Url, cptr->Host, 0);
		StrBufAppendBufPlain(cptr->Url, HKEY("/"), 0);
		StrBufUrlescAppend(cptr->Url, cptr->RoomName, NULL);

		ParseURL(&cptr->IO.ConnectMe, cptr->Url, 110);


#if 0
/* todo: we need to reunite the url to be shure. */

		pthread_mutex_lock(&POP3ueueMutex);
		GetHash(POP3FetchUrls, SKEY(ptr->Url), &vptr);
		use_this_cptr = (pop3aggr *)vptr;

		if (use_this_rncptr != NULL)
		{
			/* mustn't attach to an active session */
			if (use_this_cptr->RefCount > 0)
			{
				DeletePOP3Cfg(cptr);
///						Count->count--;
			}
			else
			{
				long *QRnumber;
				StrBufAppendBufPlain(
					use_this_cptr->rooms,
					qrbuf->QRname,
					-1, 0);
				if (use_this_cptr->roomlist_parts == 1)
				{
					use_this_cptr->OtherQRnumbers
						= NewHash(1, lFlathash);
				}
				QRnumber = (long*)malloc(sizeof(long));
				*QRnumber = qrbuf->QRnumber;
				Put(use_this_cptr->OtherQRnumbers,
				    LKEY(qrbuf->QRnumber),
				    QRnumber,
				    NULL);

				use_this_cptr->roomlist_parts++;
			}
			pthread_mutex_unlock(&POP3QueueMutex);
			continue;
		}
		pthread_mutex_unlock(&RSSQueueMutex);
#endif
		cptr->n = Pop3ClientID++;
		pthread_mutex_lock(&POP3QueueMutex);
		Put(POP3FetchUrls,
		    SKEY(cptr->Url),
		    cptr,
		    DeletePOP3Aggregator);

		pthread_mutex_unlock(&POP3QueueMutex);
		pLine = pLine->next;

	}
}
예제 #18
0
파일: notes.c 프로젝트: mingodad/citadel
/*
 * 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;
}
예제 #19
0
/*
 * Sanitize and enhance an HTML message for display.
 * Also convert weird character sets to UTF-8 if necessary.
 * Also fixup img src="cid:..." type inline images to fetch the image
 *
 */
void output_html(const char *supplied_charset, int treat_as_wiki, int msgnum, StrBuf *Source, StrBuf *Target) {
	char buf[SIZ];
	char *msg;
	char *ptr;
	char *msgstart;
	char *msgend;
	StrBuf *converted_msg;
	int buffer_length = 1;
	int line_length = 0;
	int content_length = 0;
	char new_window[SIZ];
	int brak = 0;
	int alevel = 0;
	int scriptlevel = 0;
	int script_start_pos = (-1);
	int i;
	int linklen;
	char charset[128];
	StrBuf *BodyArea = NULL;
#ifdef HAVE_ICONV
	iconv_t ic = (iconv_t)(-1) ;
	char *ibuf;                   /* Buffer of characters to be converted */
	char *obuf;                   /* Buffer for converted characters      */
	size_t ibuflen;               /* Length of input buffer               */
	size_t obuflen;               /* Length of output buffer              */
	char *osav;                   /* Saved pointer to output buffer       */
#endif
	if (Target == NULL)
		Target = WC->WBuf;

	safestrncpy(charset, supplied_charset, sizeof charset);
	msg = strdup("");
	sprintf(new_window, "<a target=\"%s\" href=", TARGET);

	if (Source == NULL) while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) {
		line_length = strlen(buf);
		buffer_length = content_length + line_length + 2;
		ptr = realloc(msg, buffer_length);
		if (ptr == NULL) {
			StrBufAppendPrintf(Target, "<b>");
			StrBufAppendPrintf(Target, _("realloc() error! couldn't get %d bytes: %s"),
					buffer_length + 1,
					strerror(errno));
			StrBufAppendPrintf(Target, "</b><br><br>\n");
			while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) {
				/** flush */
			}
			free(msg);
			return;
		}
		msg = ptr;
		strcpy(&msg[content_length], buf);
		content_length += line_length;
		strcpy(&msg[content_length], "\n");
		content_length += 1;
	}
	else {
		content_length = StrLength(Source);
		free(msg);
		msg = (char*) ChrPtr(Source);/* TODO: remove cast */
		buffer_length = content_length;
	}

	/** Do a first pass to isolate the message body */
	ptr = msg + 1;
	msgstart = msg;
	msgend = &msg[content_length];

	while (ptr < msgend) {

		/** Advance to next tag */
		ptr = strchr(ptr, '<');
		if ((ptr == NULL) || (ptr >= msgend)) break;
		++ptr;
		if ((ptr == NULL) || (ptr >= msgend)) break;

		/*
		 *  Look for META tags.  Some messages (particularly in
		 *  Asian locales) illegally declare a message's character
		 *  set in the HTML instead of in the MIME headers.  This
		 *  is wrong but we have to work around it anyway.
		 */
		if (!strncasecmp(ptr, "META", 4)) {

			char *meta_start;
			char *meta_end;
			int meta_length;
			char *meta;
			char *meta_http_equiv;
			char *meta_content;
			char *spaceptr;

			meta_start = &ptr[4];
			meta_end = strchr(ptr, '>');
			if ((meta_end != NULL) && (meta_end <= msgend)) {
				meta_length = meta_end - meta_start + 1;
				meta = malloc(meta_length + 1);
				safestrncpy(meta, meta_start, meta_length);
				meta[meta_length] = 0;
				striplt(meta);
				if (!strncasecmp(meta, "HTTP-EQUIV=", 11)) {
					meta_http_equiv = strdup(&meta[11]);
					spaceptr = strchr(meta_http_equiv, ' ');
					if (spaceptr != NULL) {
						*spaceptr = 0;
						meta_content = strdup(++spaceptr);
						if (!strncasecmp(meta_content, "content=", 8)) {
							strcpy(meta_content, &meta_content[8]);
							stripquotes(meta_http_equiv);
							stripquotes(meta_content);
							extract_charset_from_meta(charset,
									meta_http_equiv, meta_content);
						}
						free(meta_content);
					}
					free(meta_http_equiv);
				}
				free(meta);
			}
		}

		/*
		 * Any of these tags cause everything up to and including
		 * the tag to be removed.
		 */	
		if ( (!strncasecmp(ptr, "HTML", 4))
				||(!strncasecmp(ptr, "HEAD", 4))
				||(!strncasecmp(ptr, "/HEAD", 5))
				||(!strncasecmp(ptr, "BODY", 4)) ) {
			char *pBody = NULL;

			if (!strncasecmp(ptr, "BODY", 4)) {
				pBody = ptr;
			}
			ptr = strchr(ptr, '>');
			if ((ptr == NULL) || (ptr >= msgend)) break;
			if ((pBody != NULL) && (ptr - pBody > 4)) {
				char* src;
				char *cid_start, *cid_end;

				*ptr = '\0';
				pBody += 4; 
				while ((isspace(*pBody)) && (pBody < ptr))
					pBody ++;
				BodyArea = NewStrBufPlain(NULL,  ptr - pBody);

				if (pBody < ptr) {
					src = strstr(pBody, "cid:");
					if (src) {
						cid_start = src + 4;
						cid_end = cid_start;
						while ((*cid_end != '"') && 
								!isspace(*cid_end) &&
								(cid_end < ptr))
							cid_end ++;

						/* copy tag and attributes up to src="cid: */
						StrBufAppendBufPlain(BodyArea, pBody, src - pBody, 0);

						/* add in /webcit/mimepart/<msgno>/CID/ 
						   trailing / stops dumb URL filters getting excited */
						StrBufAppendPrintf(BodyArea,
								"/webcit/mimepart/%d/",msgnum);
						StrBufAppendBufPlain(BodyArea, cid_start, cid_end - cid_start, 0);

						if (ptr - cid_end > 0)
							StrBufAppendBufPlain(BodyArea, 
									cid_end + 1, 
									ptr - cid_end, 0);
					}
					else 
						StrBufAppendBufPlain(BodyArea, pBody, ptr - pBody, 0);
				}
				*ptr = '>';
			}
			++ptr;
			if ((ptr == NULL) || (ptr >= msgend)) break;
			msgstart = ptr;
		}

		/*
		 * Any of these tags cause everything including and following
		 * the tag to be removed.
		 */
		if ( (!strncasecmp(ptr, "/HTML", 5))
				||(!strncasecmp(ptr, "/BODY", 5)) ) {
			--ptr;
			msgend = ptr;
			strcpy(ptr, "");

		}

		++ptr;
	}
	if (msgstart > msg) {
		strcpy(msg, msgstart);
	}

	/* Now go through the message, parsing tags as necessary. */
	converted_msg = NewStrBufPlain(NULL, content_length + 8192);


	/** Convert foreign character sets to UTF-8 if necessary. */
#ifdef HAVE_ICONV
	if ( (strcasecmp(charset, "us-ascii"))
			&& (strcasecmp(charset, "UTF-8"))
			&& (strcasecmp(charset, ""))
	   ) {
		syslog(LOG_DEBUG, "Converting %s to UTF-8\n", charset);
		ctdl_iconv_open("UTF-8", charset, &ic);
		if (ic == (iconv_t)(-1) ) {
			syslog(LOG_WARNING, "%s:%d iconv_open() failed: %s\n",
					__FILE__, __LINE__, strerror(errno));
		}
	}
	if  (Source == NULL) {
		if (ic != (iconv_t)(-1) ) {
			ibuf = msg;
			ibuflen = content_length;
			obuflen = content_length + (content_length / 2) ;
			obuf = (char *) malloc(obuflen);
			osav = obuf;
			iconv(ic, &ibuf, &ibuflen, &obuf, &obuflen);
			content_length = content_length + (content_length / 2) - obuflen;
			osav[content_length] = 0;
			free(msg);
			msg = osav;
			iconv_close(ic);
		}
	}
	else {
		if (ic != (iconv_t)(-1) ) {
			StrBuf *Buf = NewStrBufPlain(NULL, StrLength(Source) + 8096);;
			StrBufConvert(Source, Buf, &ic);
			FreeStrBuf(&Buf);
			iconv_close(ic);
			msg = (char*)ChrPtr(Source); /* TODO: get rid of this. */
		}
	}

#endif

	/*
	 *	At this point, the message has been stripped down to
	 *	only the content inside the <BODY></BODY> tags, and has
	 *	been converted to UTF-8 if it was originally in a foreign
	 *	character set.  The text is also guaranteed to be null
	 *	terminated now.
	 */

	if (converted_msg == NULL) {
		StrBufAppendPrintf(Target, "Error %d: %s<br>%s:%d", errno, strerror(errno), __FILE__, __LINE__);
		goto BAIL;
	}

	if (BodyArea != NULL) {
		StrBufAppendBufPlain(converted_msg, HKEY("<table "), 0);  
		StrBufAppendBuf(converted_msg, BodyArea, 0);
		StrBufAppendBufPlain(converted_msg, HKEY(" width=\"100%\"><tr><td>"), 0);
	}
	ptr = msg;
	msgend = strchr(msg, 0);
	while (ptr < msgend) {

		/** Try to sanitize the html of any rogue scripts */
		if (!strncasecmp(ptr, "<script", 7)) {
			if (scriptlevel == 0) {
				script_start_pos = StrLength(converted_msg);
			}
			++scriptlevel;
		}
		if (!strncasecmp(ptr, "</script", 8)) {
			--scriptlevel;
		}

		/**
		 * Change mailto: links to WebCit mail, by replacing the
		 * link with one that points back to our mail room.  Due to
		 * the way we parse URL's, it'll even handle mailto: links
		 * that have "?subject=" in them.
		 */
		if (!strncasecmp(ptr, "<a href=\"mailto:", 16)) {
			content_length += 64;
			StrBufAppendPrintf(converted_msg,
					"<a href=\"display_enter?force_room=_MAIL_?recp=");
			ptr = &ptr[16];
			++alevel;
			++brak;
		}
		/** Make external links open in a separate window */
		else if (!strncasecmp(ptr, "<a href=\"", 9)) {
			++alevel;
			++brak;
			if ( ((strchr(ptr, ':') < strchr(ptr, '/')))
					&&  ((strchr(ptr, '/') < strchr(ptr, '>'))) 
			   ) {
				/* open external links to new window */
				StrBufAppendPrintf(converted_msg, new_window);
				ptr = &ptr[8];
			}
			else if (
				(treat_as_wiki)
				&& (strncasecmp(ptr, "<a href=\"wiki?", 14))
				&& (strncasecmp(ptr, "<a href=\"dotgoto?", 17))
				&& (strncasecmp(ptr, "<a href=\"knrooms?", 17))
			) {
				content_length += 64;
				StrBufAppendPrintf(converted_msg, "<a href=\"wiki?go=");
				StrBufUrlescAppend(converted_msg, WC->CurRoom.name, NULL);
				StrBufAppendPrintf(converted_msg, "?page=");
				ptr = &ptr[9];
			}
			else {
				StrBufAppendPrintf(converted_msg, "<a href=\"");
				ptr = &ptr[9];
			}
		}
		/** Fixup <img src="cid:... ...> to fetch the mime part */
		else if (!strncasecmp(ptr, "<img ", 5)) {
			char *cid_start, *cid_end;
			char* tag_end=strchr(ptr,'>');
			char* src;
			/* FIXME - handle this situation (maybe someone opened an <img cid... 
			 * and then ended the message)
			 */
			if (!tag_end) {
				syslog(LOG_DEBUG, "tag_end is null and ptr is:\n");
				syslog(LOG_DEBUG, "%s\n", ptr);
				syslog(LOG_DEBUG, "Theoretical bytes remaining: %d\n", (int)(msgend - ptr));
			}

			src=strstr(ptr, "src=\"cid:");
			++brak;

			if (src
			    && isspace(*(src-1))
				&& tag_end
				&& (cid_start=strchr(src,':'))
				&& (cid_end=strchr(cid_start,'"'))
				&& (cid_end < tag_end)
			) {
				/* copy tag and attributes up to src="cid: */
				StrBufAppendBufPlain(converted_msg, ptr, src - ptr, 0);
				cid_start++;

				/* add in /webcit/mimepart/<msgno>/CID/ 
				   trailing / stops dumb URL filters getting excited */
				StrBufAppendPrintf(converted_msg,
						" src=\"/webcit/mimepart/%d/",msgnum);
				StrBufAppendBufPlain(converted_msg, cid_start, cid_end - cid_start, 0);
				StrBufAppendBufPlain(converted_msg, "/\"", -1, 0);

				ptr = cid_end+1;
			}
			StrBufAppendBufPlain(converted_msg, ptr, tag_end - ptr, 0);
			ptr = tag_end;
		}

		/**
		 * Turn anything that looks like a URL into a real link, as long
		 * as it's not inside a tag already
		 */
		else if ( (brak == 0) && (alevel == 0) &&
			  ( (!strncasecmp(ptr, "http://", 7)) ||
			    (!strncasecmp(ptr, "https://", 8)))) {
			/** Find the end of the link */
			int strlenptr;
			linklen = 0;
				
			strlenptr = strlen(ptr);
			for (i=0; i<=strlenptr; ++i) {
				if ((ptr[i]==0)
				    ||(isspace(ptr[i]))
				    ||(ptr[i]==10)
				    ||(ptr[i]==13)
				    ||(ptr[i]=='(')
				    ||(ptr[i]==')')
				    ||(ptr[i]=='<')
				    ||(ptr[i]=='>')
				    ||(ptr[i]=='[')
				    ||(ptr[i]==']')
				    ||(ptr[i]=='"')
				    ||(ptr[i]=='\'')
					) linklen = i;
				/* did s.b. send us an entity? */
				if (ptr[i] == '&') {
					if ((ptr[i+2] ==';') ||
					    (ptr[i+3] ==';') ||
					    (ptr[i+5] ==';') ||
					    (ptr[i+6] ==';') ||
					    (ptr[i+7] ==';'))
						linklen = i;
				}
				if (linklen > 0) break;
			}
			if (linklen > 0) {
				char *ltreviewptr;
				char *nbspreviewptr;
				char linkedchar;
				int len;
					
				len = linklen;
				linkedchar = ptr[len];
				ptr[len] = '\0';
				/* spot for some subject strings tinymce tends to give us. */
				ltreviewptr = strchr(ptr, '<');
				if (ltreviewptr != NULL) {
					*ltreviewptr = '\0';
					linklen = ltreviewptr - ptr;
				}

				nbspreviewptr = strstr(ptr, "&nbsp;");
				if (nbspreviewptr != NULL) {
					/* nbspreviewptr = '\0'; */
					linklen = nbspreviewptr - ptr;
				}
				if (ltreviewptr != 0)
					*ltreviewptr = '<';

				ptr[len] = linkedchar;

				content_length += (32 + linklen);
				StrBufAppendPrintf(converted_msg, "%s\"", new_window);
				StrBufAppendBufPlain(converted_msg, ptr, linklen, 0);
				StrBufAppendPrintf(converted_msg, "\">");
				StrBufAppendBufPlain(converted_msg, ptr, linklen, 0);
				ptr += linklen;
				StrBufAppendPrintf(converted_msg, "</A>");
			}
		}
		else {
			StrBufAppendBufPlain(converted_msg, ptr, 1, 0);
			ptr++;
		}


		if ((ptr >= msg) && (ptr <= msgend)) {
			/*
			 * We need to know when we're inside a tag,
			 * so we don't turn things that look like URL's into
			 * links, when they're already links - or image sources.
			 */
			if ((ptr > msg) && (*(ptr-1) == '<')) {
				++brak;
			}
			if ((ptr > msg) && (*(ptr-1) == '>')) {
				--brak;
				if ((scriptlevel == 0) && (script_start_pos >= 0)) {
					StrBufCutRight(converted_msg, StrLength(converted_msg) - script_start_pos);
					script_start_pos = (-1);
				}
			}
			if (!strncasecmp(ptr, "</A>", 3)) --alevel;
		}
	}

	if (BodyArea != NULL) {
		StrBufAppendBufPlain(converted_msg, HKEY("</td></tr></table>"), 0);  
		FreeStrBuf(&BodyArea);
	}

	/**	uncomment these two lines to override conversion	*/
	/**	memcpy(converted_msg, msg, content_length);		*/
	/**	output_length = content_length;				*/

	/** Output our big pile of markup */
	StrBufAppendBuf(Target, converted_msg, 0);

BAIL:	/** A little trailing vertical whitespace... */
	StrBufAppendPrintf(Target, "<br><br>\n");

	/** Now give back the memory */
	FreeStrBuf(&converted_msg);
	if ((msg != NULL) && (Source == NULL)) free(msg);
}
예제 #20
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");
}
예제 #21
0
/*
 * Read in the request
 */
int ReadHTTPRequest (ParsedHttpHdrs *Hdr)
{
	const char *pch, *pchs, *pche;
	OneHttpHeader *pHdr;
	StrBuf *Line, *LastLine, *HeaderName;
	int nLine = 0;
	void *vF;
	int isbogus = 0;

	HeaderName = NewStrBuf();
	LastLine = NULL;
	do {
		nLine ++;
		Line = NewStrBufPlain(NULL, SIZ / 4);

		if (ClientGetLine(Hdr, Line) < 0) return 1;

		if (StrLength(Line) == 0) {
			FreeStrBuf(&Line);
			continue;
		}
		if (nLine == 1) {
			Hdr->HTTPHeaders = NewHash(1, NULL);
			pHdr = (OneHttpHeader*) malloc(sizeof(OneHttpHeader));
			memset(pHdr, 0, sizeof(OneHttpHeader));
			pHdr->Val = Line;
			Put(Hdr->HTTPHeaders, HKEY("GET /"), pHdr, DestroyHttpHeaderHandler);
			if (verbose || strstr(ChrPtr(Line), "sslg") == NULL)
				syslog(LOG_DEBUG, "%s", ChrPtr(Line));
			isbogus = ReadHttpSubject(Hdr, Line, HeaderName);
			if (isbogus) break;
			continue;
		}

		/* Do we need to Unfold? */
		if ((LastLine != NULL) && 
		    (isspace(*ChrPtr(Line)))) {
			pch = pchs = ChrPtr(Line);
			pche = pchs + StrLength(Line);
			while (isspace(*pch) && (pch < pche))
				pch ++;
			StrBufCutLeft(Line, pch - pchs);
			StrBufAppendBuf(LastLine, Line, 0);

			FreeStrBuf(&Line);
			continue;
		}

		StrBufSanitizeAscii(Line, (char)0xa7);
		StrBufExtract_token(HeaderName, Line, 0, ':');

		pchs = ChrPtr(Line);
		pche = pchs + StrLength(Line);
		pch = pchs + StrLength(HeaderName) + 1;
		pche = pchs + StrLength(Line);
		while ((pch < pche) && isspace(*pch))
			pch ++;
		StrBufCutLeft(Line, pch - pchs);

		StrBufUpCase(HeaderName);

		pHdr = (OneHttpHeader*) malloc(sizeof(OneHttpHeader));
		memset(pHdr, 0, sizeof(OneHttpHeader));
		pHdr->Val = Line;

		if (GetHash(HttpHeaderHandler, SKEY(HeaderName), &vF) &&
		    (vF != NULL))
		{
			OneHttpHeader *FHdr = (OneHttpHeader*) vF;
			pHdr->H = FHdr->H;
			pHdr->HaveEvaluator = 1;
		}
		Put(Hdr->HTTPHeaders, SKEY(HeaderName), pHdr, DestroyHttpHeaderHandler);
		LastLine = Line;
	} while (Line != NULL);

	FreeStrBuf(&HeaderName);

	return isbogus;
}
예제 #22
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 smtpq_do_bounce(OneQueItem *MyQItem, StrBuf *OMsgTxt, ParsedURL *Relay)
{
	static int seq = 0;
	
	struct CtdlMessage *bmsg = NULL;
	StrBuf *boundary;
	StrBuf *Msg = NULL;
	StrBuf *BounceMB;
	recptypes *valid;
	time_t now;

	HashPos *It;
	void *vQE;
	long len;
	const char *Key;

	int first_attempt = 0;
	int successful_bounce = 0;
	int num_bounces = 0;
	int give_up = 0;

	SMTPCM_syslog(LOG_DEBUG, "smtp_do_bounce() called\n");

	if (MyQItem->SendBounceMail == 0)
		return;

	now = time (NULL); //ev_time();

	if ( (now - MyQItem->Submitted) > SMTP_GIVE_UP ) {
		give_up = 1;
	}

	if (MyQItem->Retry == SMTP_RETRY_INTERVAL) {
		first_attempt = 1;
	}

	/*
	 * Now go through the instructions checking for stuff.
	 */
	Msg = NewStrBufPlain(NULL, 1024);
	It = GetNewHashPos(MyQItem->MailQEntries, 0);
	while (GetNextHashPos(MyQItem->MailQEntries, It, &len, &Key, &vQE))
	{
		MailQEntry *ThisItem = vQE;
		if ((ThisItem->Active && (ThisItem->Status == 5)) || /* failed now? */
		    ((give_up == 1) && (ThisItem->Status != 2)) ||
		    ((first_attempt == 1) && (ThisItem->Status != 2)))
			/* giving up after failed attempts... */
		{
			++num_bounces;

			StrBufAppendBufPlain(Msg, HKEY(" "), 0);
			StrBufAppendBuf(Msg, ThisItem->Recipient, 0);
			StrBufAppendBufPlain(Msg, HKEY(": "), 0);
			if (ThisItem->AllStatusMessages != NULL)
				StrBufAppendBuf(Msg, ThisItem->AllStatusMessages, 0);
			else
				StrBufAppendBuf(Msg, ThisItem->StatusMessage, 0);
			StrBufAppendBufPlain(Msg, HKEY("\r\n"), 0);
		}
	}
	DeleteHashPos(&It);

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

	if (num_bounces == 0) {
		FreeStrBuf(&Msg);
		return;
	}

	if ((StrLength(MyQItem->SenderRoom) == 0) && MyQItem->HaveRelay) {
		const char *RelayUrlStr = "[not found]";
		/* one message that relaying is broken is enough; no extra room error message. */
		StrBuf *RelayDetails = NewStrBuf();

		if (Relay != NULL)
			RelayUrlStr = ChrPtr(Relay->URL);

		StrBufPrintf(RelayDetails,
			     "Relaying via %s failed permanently. \n Reason:\n%s\n Revalidate your relay configuration.",
			     RelayUrlStr,
			     ChrPtr(Msg));
                CtdlAideMessage(ChrPtr(RelayDetails), "Relaying Failed");
		FreeStrBuf(&RelayDetails);
	}

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

	/* Start building our bounce message; go shopping for memory first. */
	BounceMB = NewStrBufPlain(
		NULL,
		1024 + /* mime stuff.... */
		StrLength(Msg) +  /* the bounce information... */
		StrLength(OMsgTxt)); /* the original message */
	if (BounceMB == NULL) {
		FreeStrBuf(&boundary);
		SMTPCM_syslog(LOG_ERR, "Failed to alloc() bounce message.\n");

		return;
	}

	bmsg = (struct CtdlMessage *) malloc(sizeof(struct CtdlMessage));
	if (bmsg == NULL) {
		FreeStrBuf(&boundary);
		FreeStrBuf(&BounceMB);
		SMTPCM_syslog(LOG_ERR, "Failed to alloc() bounce message.\n");

		return;
	}
	memset(bmsg, 0, sizeof(struct CtdlMessage));


	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\n"
				"due 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);

	StrBufAppendBuf(BounceMB, Msg, 0);
	FreeStrBuf(&Msg);

	if (StrLength(MyQItem->SenderRoom) > 0)
	{
		StrBufAppendBufPlain(
			BounceMB,
			HKEY("The message was originaly posted in: "), 0);
		StrBufAppendBuf(BounceMB, MyQItem->SenderRoom, 0);
		StrBufAppendBufPlain(
			BounceMB,
			HKEY("\n"), 0);
	}

	/* Attach the original message */
	StrBufAppendBufPlain(BounceMB, HKEY("\r\n--"), 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);
	StrBufAppendBuf(BounceMB, OMsgTxt, 0);

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

	bmsg->cm_magic = CTDLMESSAGE_MAGIC;
	bmsg->cm_anon_type = MES_NORMAL;
	bmsg->cm_format_type = FMT_RFC822;

	CM_SetField(bmsg, eOriginalRoom, HKEY(MAILROOM));
	CM_SetField(bmsg, eAuthor, HKEY("Citadel"));
	CM_SetField(bmsg, eNodeName, CtdlGetConfigStr("c_nodename"), strlen(CtdlGetConfigStr("c_nodename")));
	CM_SetField(bmsg, eMsgSubject, HKEY("Delivery Status Notification (Failure)"));
	CM_SetAsFieldSB(bmsg, eMesageText, &BounceMB);

	/* First try the user who sent the message */
	if (StrLength(MyQItem->BounceTo) == 0) {
		SMTPCM_syslog(LOG_ERR, "No bounce address specified\n");
	}
	else {
		SMTPC_syslog(LOG_DEBUG, "bounce to user? <%s>\n",
		       ChrPtr(MyQItem->BounceTo));
	}

	/* Can we deliver the bounce to the original sender? */
	valid = validate_recipients(ChrPtr(MyQItem->BounceTo), NULL, 0);
	if ((valid != NULL) && (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 */
	free_recipients(valid);
	FreeStrBuf(&boundary);
	CM_Free(bmsg);
	SMTPCM_syslog(LOG_DEBUG, "Done processing bounces\n");
}
예제 #23
0
int ReadHttpSubject(ParsedHttpHdrs *Hdr, StrBuf *Line, StrBuf *Buf)
{
	const char *Args;
	void *vLine, *vHandler;
	const char *Pos = NULL;

	Hdr->HR.ReqLine = Line;
	/* The requesttype... GET, POST... */
	StrBufExtract_token(Buf, Hdr->HR.ReqLine, 0, ' ');
	if (GetHash(HttpReqTypes, SKEY(Buf), &vLine) &&
	    (vLine != NULL))
	{
		Hdr->HR.eReqType = *(long*)vLine;
	}
	else {
		Hdr->HR.eReqType = eGET;
		return 1;
	}
	StrBufCutLeft(Hdr->HR.ReqLine, StrLength(Buf) + 1);

	/* the HTTP Version... */
	StrBufExtract_token(Buf, Hdr->HR.ReqLine, 1, ' ');
	StrBufCutRight(Hdr->HR.ReqLine, StrLength(Buf) + 1);
	
	if (StrLength(Buf) == 0) {
		Hdr->HR.eReqType = eGET;
		return 1;
	}

	StrBufAppendBuf(Hdr->this_page, Hdr->HR.ReqLine, 0);

	/* chop Filename / query arguments */
	Args = strchr(ChrPtr(Hdr->HR.ReqLine), '?');
	if (Args == NULL) /* whe're not that picky about params... TODO: this will spoil '&' in filenames.*/
		Args = strchr(ChrPtr(Hdr->HR.ReqLine), '&');
	if (Args != NULL) {
		Args ++; /* skip the ? */
		StrBufPlain(Hdr->PlainArgs, 
			    Args, 
			    StrLength(Hdr->HR.ReqLine) -
			    (Args - ChrPtr(Hdr->HR.ReqLine)));
		StrBufCutAt(Hdr->HR.ReqLine, 0, Args - 1);
	} /* don't parse them yet, maybe we don't even care... */
	
	/* now lookup what we are going to do with this... */
	/* skip first slash */
	StrBufExtract_NextToken(Buf, Hdr->HR.ReqLine, &Pos, '/');
	do {
		StrBufExtract_NextToken(Buf, Hdr->HR.ReqLine, &Pos, '/');

		GetHash(HandlerHash, SKEY(Buf), &vHandler),
		Hdr->HR.Handler = (WebcitHandler*) vHandler;
		if (Hdr->HR.Handler == NULL)
			break;
		/*
		 * If the request is prefixed by "/webcit" then chop that off.  This
		 * allows a front end web server to forward all /webcit requests to us
		 * while still using the same web server port for other things.
		 */
		if ((Hdr->HR.Handler->Flags & URLNAMESPACE) != 0)
			continue;
		break;
	} while (1);
	/* remove the handlername from the URL */
	if ((Pos != NULL) && (Pos != StrBufNOTNULL)){
		StrBufCutLeft(Hdr->HR.ReqLine, 
			      Pos - ChrPtr(Hdr->HR.ReqLine));
	}

	if (Hdr->HR.Handler != NULL) {
		if ((Hdr->HR.Handler->Flags & BOGUS) != 0) {
			return 1;
		}
		Hdr->HR.DontNeedAuth = (
			((Hdr->HR.Handler->Flags & ISSTATIC) != 0) ||
			((Hdr->HR.Handler->Flags & ANONYMOUS) != 0)
		);
	}
	else {
		/* If this is a "flat" request for the root, display the configured landing page. */
		int return_value;
		StrBuf *NewLine = NewStrBuf();
		Hdr->HR.DontNeedAuth = 1;
		StrBufAppendPrintf(NewLine, "GET /landing?go=%s?failvisibly=1 HTTP/1.0", ChrPtr(Buf));
		if (verbose) syslog(LOG_DEBUG, "Replacing with: %s", ChrPtr(NewLine));
		return_value = ReadHttpSubject(Hdr, NewLine, Buf);
		FreeStrBuf(&NewLine);
		return return_value;
	}

	return 0;
}
예제 #24
0
/*
 * Setup an OpenID authentication
 */
void cmd_oids(char *argbuf) {
	struct CitContext *CCC = CC;	/* CachedCitContext - performance boost */
	const char *Pos = NULL;
	StrBuf *ArgBuf = NULL;
	StrBuf *ReplyBuf = NULL;
	StrBuf *return_to = NULL;
	StrBuf *RedirectUrl = NULL;
	ctdl_openid *oiddata;
	int discovery_succeeded = 0;

	if (CtdlGetConfigInt("c_disable_newu"))
	{
		cprintf("%d this system does not support openid.\n",
			ERROR + CMD_NOT_SUPPORTED);
		return;
	}
	Free_ctdl_openid ((ctdl_openid**)&CCC->openid_data);

	CCC->openid_data = oiddata = malloc(sizeof(ctdl_openid));
	if (oiddata == NULL) {
		syslog(LOG_ALERT, "malloc() failed: %s", strerror(errno));
		cprintf("%d malloc failed\n", ERROR + INTERNAL_ERROR);
		return;
	}
	memset(oiddata, 0, sizeof(ctdl_openid));

	ArgBuf = NewStrBufPlain(argbuf, -1);

	oiddata->verified = 0;
	oiddata->claimed_id = NewStrBufPlain(NULL, StrLength(ArgBuf));
	return_to = NewStrBufPlain(NULL, StrLength(ArgBuf));

	StrBufExtract_NextToken(oiddata->claimed_id, ArgBuf, &Pos, '|');
	StrBufExtract_NextToken(return_to, ArgBuf, &Pos, '|');

	syslog(LOG_DEBUG, "User-Supplied Identifier is: %s", ChrPtr(oiddata->claimed_id));

	/********** OpenID 2.0 section 7.3 - Discovery **********/

	/* Section 7.3.1 says we have to attempt XRI based discovery.
	 * No one is using this, no one is asking for it, no one wants it.
	 * So we're not even going to bother attempting this mode.
	 */

	/* Attempt section 7.3.2 (Yadis discovery) and section 7.3.3 (HTML discovery);
	 */
	discovery_succeeded = perform_openid2_discovery(oiddata->claimed_id);

	if (discovery_succeeded == 0) {
		cprintf("%d There is no OpenID identity provider at this location.\n", ERROR);
	}

	else {
		/*
		 * If we get to this point we are in possession of a valid OpenID Provider URL.
		 */
		syslog(LOG_DEBUG, "OP URI '%s' discovered using method %d",
			ChrPtr(oiddata->op_url),
			discovery_succeeded
		);

		/* We have to "normalize" our Claimed ID otherwise it will cause some OP's to barf */
		if (cbmstrcasestr(ChrPtr(oiddata->claimed_id), "://") == NULL) {
			StrBuf *cid = oiddata->claimed_id;
			oiddata->claimed_id = NewStrBufPlain(HKEY("http://"));
			StrBufAppendBuf(oiddata->claimed_id, cid, 0);
			FreeStrBuf(&cid);
		}

		/*
		 * OpenID 2.0 section 9: request authentication
		 * Assemble a URL to which the user-agent will be redirected.
		 */
	
		RedirectUrl = NewStrBufDup(oiddata->op_url);

		StrBufAppendBufPlain(RedirectUrl, HKEY("?openid.ns="), 0);
		StrBufUrlescAppend(RedirectUrl, NULL, "http://specs.openid.net/auth/2.0");

		StrBufAppendBufPlain(RedirectUrl, HKEY("&openid.mode=checkid_setup"), 0);

		StrBufAppendBufPlain(RedirectUrl, HKEY("&openid.claimed_id="), 0);
		StrBufUrlescAppend(RedirectUrl, oiddata->claimed_id, NULL);

		StrBufAppendBufPlain(RedirectUrl, HKEY("&openid.identity="), 0);
		StrBufUrlescAppend(RedirectUrl, oiddata->claimed_id, NULL);

		/* return_to tells the provider how to complete the round trip back to our site */
		StrBufAppendBufPlain(RedirectUrl, HKEY("&openid.return_to="), 0);
		StrBufUrlescAppend(RedirectUrl, return_to, NULL);

		/* Attribute Exchange
		 * See:
		 *	http://openid.net/specs/openid-attribute-exchange-1_0.html
		 *	http://code.google.com/apis/accounts/docs/OpenID.html#endpoint
		 * 	http://test-id.net/OP/AXFetch.aspx
		 */

		StrBufAppendBufPlain(RedirectUrl, HKEY("&openid.ns.ax="), 0);
		StrBufUrlescAppend(RedirectUrl, NULL, "http://openid.net/srv/ax/1.0");

		StrBufAppendBufPlain(RedirectUrl, HKEY("&openid.ax.mode=fetch_request"), 0);

		StrBufAppendBufPlain(RedirectUrl, HKEY("&openid.ax.required=firstname,lastname,friendly,nickname"), 0);

		StrBufAppendBufPlain(RedirectUrl, HKEY("&openid.ax.type.firstname="), 0);
		StrBufUrlescAppend(RedirectUrl, NULL, "http://axschema.org/namePerson/first");

		StrBufAppendBufPlain(RedirectUrl, HKEY("&openid.ax.type.lastname="), 0);
		StrBufUrlescAppend(RedirectUrl, NULL, "http://axschema.org/namePerson/last");

		StrBufAppendBufPlain(RedirectUrl, HKEY("&openid.ax.type.friendly="), 0);
		StrBufUrlescAppend(RedirectUrl, NULL, "http://axschema.org/namePerson/friendly");

		StrBufAppendBufPlain(RedirectUrl, HKEY("&openid.ax.type.nickname="), 0);
		StrBufUrlescAppend(RedirectUrl, NULL, "http://axschema.org/namePerson/nickname");

		syslog(LOG_DEBUG, "OpenID: redirecting client to %s", ChrPtr(RedirectUrl));
		cprintf("%d %s\n", CIT_OK, ChrPtr(RedirectUrl));
	}
	
	FreeStrBuf(&ArgBuf);
	FreeStrBuf(&ReplyBuf);
	FreeStrBuf(&return_to);
	FreeStrBuf(&RedirectUrl);
}
예제 #25
0
파일: nttlist.c 프로젝트: mingodad/citadel
int CtdlNetworkTalkingTo(const char *nodename, long len, int operation)
{

	int retval = 0;
	HashPos *Pos = NULL;
	void *vdata;

	begin_critical_section(S_NTTLIST);

	switch(operation) {

		case NTT_ADD:
			if (nttlist == NULL) 
				nttlist = NewHash(1, NULL);
			Put(nttlist, nodename, len, NewStrBufPlain(nodename, len), HFreeStrBuf);
			if (NTTDebugEnabled) syslog(LOG_DEBUG, "nttlist: added <%s>\n", nodename);
			break;
		case NTT_REMOVE:
			if ((nttlist == NULL) ||
			    (GetCount(nttlist) == 0))
				break;
			Pos = GetNewHashPos(nttlist, 1);
			if (GetHashPosFromKey (nttlist, nodename, len, Pos))
				DeleteEntryFromHash(nttlist, Pos);
			DeleteHashPos(&Pos);
			if (NTTDebugEnabled) syslog(LOG_DEBUG, "nttlist: removed <%s>\n", nodename);

			break;

		case NTT_CHECK:
			if ((nttlist == NULL) ||
			    (GetCount(nttlist) == 0))
				break;
			if (GetHash(nttlist, nodename, len, &vdata))
				retval ++;
			if (NTTDebugEnabled) syslog(LOG_DEBUG, "nttlist: have [%d] <%s>\n", retval, nodename);
			break;
	}

	if (NTTDumpEnabled)
	{
		HashPos *It;
		StrBuf *NTTDump;
		long len;
		const char *Key;
		void *v;
		NTTDump = NewStrBuf ();

		It = GetNewHashPos(nttlist, 0);
		while (GetNextHashPos(nttlist, It, &len, &Key, &v))
		{
			if (StrLength(NTTDump) > 0)
				StrBufAppendBufPlain(NTTDump, HKEY("|"), 0);
			StrBufAppendBuf(NTTDump, (StrBuf*) v, 0);
		}
		DeleteHashPos(&It);

		syslog(LOG_DEBUG, "nttlist: Dump: [%d] <%s>\n", 
		       GetCount(nttlist),
		       ChrPtr(NTTDump));
		FreeStrBuf(&NTTDump);
	}
	end_critical_section(S_NTTLIST);
	return(retval);
}