Пример #1
0
unsigned int cmd_script(callbackp *callbacki)
{
	char *domain = CONFIG_VAL(Server, domain, callbacki->g_ape->srv);
	char *script = NULL;
	int alloc = 0;
	APE_PARAMS_INIT();
	
	if (domain == NULL) {
		send_error(callbacki->call_user, "NO_DOMAIN", "201", callbacki->g_ape);
	} else {
		char *autodom;
		if (strcmp(domain, "auto") == 0 && (autodom = JSTR(domain)) != NULL) {
			domain = autodom;
			#if 0
			/* http://geekandpoke.typepad.com/.a/6a00d8341d3df553ef0120a6d65b8a970b-pi */
			
			struct _http_header_line *hlines;

			for (hlines = callbacki->client->http.hlines; hlines != NULL; hlines = hlines->next) {
				if (strcasecmp(hlines->key.val, "host") == 0) {
					char *loc;
					char *newdom = xmalloc(sizeof(char) * (hlines->value.len + 1));
					memset(newdom, '\0', hlines->value.len + 1);
					if ((loc = strrchr(hlines->value.val, '.')) != NULL) {
						int i, pos = 0;

						for (i = 0; i < hlines->value.len; i++, pos++) {
							newdom[pos] = hlines->value.val[i];
							if (newdom[pos] == ':') {
								newdom[pos] = '\0';
								break;
							}
							if (hlines->value.val[i] == '.' && &hlines->value.val[i] < loc) {
								pos = -1;
							}
						}
						newdom[pos] = '\0';
						domain = newdom;
						alloc = 1;
					}
				}
			}
			#endif		
		}
		sendf(callbacki->client->fd, callbacki->g_ape, "%s<html>\n<head>\n\t<script>\n\t\tdocument.domain=\"%s\"\n\t</script>\n", HEADER_DEFAULT, domain);
		
		if (alloc) {
			free(domain);
		}
		
		JFOREACH(scripts, script) {
			sendf(callbacki->client->fd, callbacki->g_ape, "\t<script type=\"text/javascript\" src=\"%s\"></script>\n", script);
		}
		sendbin(callbacki->client->fd, "</head>\n<body>\n</body>\n</html>", 30, 0, callbacki->g_ape);
	}
Пример #2
0
void proxy_write(ape_proxy *proxy, char *data, acetables *g_ape)
{
	char *b64;
	int len;
	if (proxy->state != PROXY_CONNECTED) {
		return;
	}
	
	b64 = xmalloc(strlen(data)+1);
	len = base64_decode(b64, data, strlen(data)+1);
	
	sendbin(proxy->sock.fd, b64, len, 0, g_ape);
	free(b64);
}
Пример #3
0
unsigned int cmd_script(callbackp *callbacki)
{
	char *domain = CONFIG_VAL(Server, domain, callbacki->g_ape->srv);
	if (domain == NULL) {
		send_error(callbacki->call_user, "NO_DOMAIN", "201", callbacki->g_ape);
	} else {
		int i;
		sendf(callbacki->fdclient, callbacki->g_ape, "%s<html>\n<head>\n\t<script>\n\t\tdocument.domain=\"%s\"\n\t</script>\n", HEADER, domain);
		for (i = 1; i <= callbacki->nParam; i++) {
			sendf(callbacki->fdclient, callbacki->g_ape, "\t<script type=\"text/javascript\" src=\"%s\"></script>\n", callbacki->param[i]);
		}
		sendbin(callbacki->fdclient, "</head>\n<body>\n</body>\n</html>", 30, callbacki->g_ape);
	}
	return (FOR_NOTHING);
}
Пример #4
0
int sendf(int sock, acetables *g_ape, char *buf, ...)
{
	char *buff;
	int len;
	int finish;
	
	va_list val;
	
	va_start(val, buf);
	len = vasprintf(&buff, buf, val);
	va_end(val);

	finish = sendbin(sock, buff, len, 0, g_ape);

	free(buff);

	return finish;
}
Пример #5
0
/*
	Send queue to socket
*/
int send_raws(subuser *user, acetables *g_ape)
{
	int finish = 1, state = 0;
	struct _raw_pool *pool;
	struct _transport_properties *properties;

	if (user->raw_pools.nraw == 0) {
		return 1;
	}

	PACK_TCP(user->client->fd); /* Activate TCP_CORK */
	
	properties = transport_get_properties(user->user->transport, g_ape);
	
	if (!user->headers.sent) {
		user->headers.sent = 1;
		
		switch(user->user->transport) {
			case TRANSPORT_XHRSTREAMING:
				finish &= http_send_headers(user->headers.content, HEADER_XHR, HEADER_XHR_LEN, user->client, g_ape);
				break;
			case TRANSPORT_SSE_LONGPOLLING:
				finish &= http_send_headers(user->headers.content, HEADER_SSE, HEADER_SSE_LEN, user->client, g_ape);
				break;
			case TRANSPORT_WEBSOCKET:
			case TRANSPORT_WEBSOCKET_IETF:
				break;
			default:
				finish &= http_send_headers(user->headers.content, HEADER_DEFAULT, HEADER_DEFAULT_LEN, user->client, g_ape);
				break;
		}
		
	}
	
	if (properties != NULL && properties->padding.left.val != NULL) {
		finish &= sendbin(user->client->fd, properties->padding.left.val, properties->padding.left.len, 0, g_ape);
	}

	if (user->raw_pools.high.nraw) {
		pool = user->raw_pools.high.rawfoot->prev;
	} else {
		pool = user->raw_pools.low.rawhead;
		state = 1;
	}
	
	if (user->user->transport == TRANSPORT_WEBSOCKET_IETF) {
	    char payload_head[32] = { 0x84 };
	    int payload_size = raws_size(user); /* TODO: fragmentation? */
	    int payload_length = 0;
	    
	    if (payload_size <= 125) {
	        payload_head[1] = (unsigned char)payload_size & 0x7F;
	        payload_length = 2;
	    } else if (payload_size <= 65535) {
	        unsigned short int s = htons(payload_size);
	        payload_head[1] = 126;
	        
	        memcpy(&payload_head[2], &s, 2);
	        
	        payload_length = 4;
	    } else if (payload_size <= 0xFFFFFFFF) {
	        unsigned int s = htonl(payload_size);
	        
	        payload_head[1] = 127;
	        payload_head[2] = 0;
	        payload_head[3] = 0;
	        payload_head[4] = 0;
	        payload_head[5] = 0;
	        
            memcpy(&payload_head[6], &s, 4);

	        payload_length = 10;
	    }
        
        finish &= sendbin(user->client->fd, payload_head, payload_length, 0, g_ape);

	}
	finish &= sendbin(user->client->fd, "[", 1, 0, g_ape);
		
	while (pool->raw != NULL) {
		struct _raw_pool *pool_next = (state ? pool->next : pool->prev);

		finish &= sendbin(user->client->fd, pool->raw->data, pool->raw->len, 0, g_ape);

		if ((pool_next != NULL && pool_next->raw != NULL) || (!state && user->raw_pools.low.nraw)) {
			finish &= sendbin(user->client->fd, ",", 1, 0, g_ape);
		} else {
			finish &= sendbin(user->client->fd, "]", 1, 0, g_ape);
			
			if (properties != NULL && properties->padding.right.val != NULL) {
				finish &= sendbin(user->client->fd, properties->padding.right.val, properties->padding.right.len, 0, g_ape);
			}
		}
		
		free_raw(pool->raw);
		pool->raw = NULL;
		
		pool = pool_next;
		
		if ((pool == NULL || pool->raw == NULL) && !state) {
			pool = user->raw_pools.low.rawhead;
			state = 1;
		}
	}
	
	user->raw_pools.high.nraw = 0;
	user->raw_pools.low.nraw = 0;
	user->raw_pools.nraw = 0;
	
	user->raw_pools.high.rawfoot = user->raw_pools.high.rawhead;
	user->raw_pools.low.rawfoot = user->raw_pools.low.rawhead;
	
	FLUSH_TCP(user->client->fd);
	
	return finish;
}
Пример #6
0
int send_raw_inline(ape_socket *client, transport_t transport, RAW *raw, acetables *g_ape)
{
	struct _transport_properties *properties;
	int finish = 1;

	properties = transport_get_properties(transport, g_ape);

	switch(transport) {
		case TRANSPORT_XHRSTREAMING:
			finish &= http_send_headers(NULL, HEADER_XHR, HEADER_XHR_LEN, client, g_ape);
			break;
		case TRANSPORT_SSE_LONGPOLLING:
			finish &= http_send_headers(NULL, HEADER_SSE, HEADER_SSE_LEN, client, g_ape);
			break;
		case TRANSPORT_WEBSOCKET:
		case TRANSPORT_WEBSOCKET_IETF:
			break;
		default:
			finish &= http_send_headers(NULL, HEADER_DEFAULT, HEADER_DEFAULT_LEN, client, g_ape);
			break;
	}
	
	if (properties != NULL && properties->padding.left.val != NULL) {
		finish &= sendbin(client->fd, properties->padding.left.val, properties->padding.left.len, 0, g_ape);
	}	


	if (transport == TRANSPORT_WEBSOCKET_IETF) {
	    char payload_head[32] = { 0x84 };
	    int payload_size = raw->len+2; /* TODO: fragmentation? */
	    int payload_length = 0;
	    
	    if (payload_size <= 125) {
	        payload_head[1] = (unsigned char)payload_size & 0x7F;
	        payload_length = 2;
	    } else if (payload_size <= 65535) {
	        unsigned short int s = htons(payload_size);
	        payload_head[1] = 126;
	        
	        memcpy(&payload_head[2], &s, 2);
	        
	        payload_length = 4;
	    } else if (payload_size <= 0xFFFFFFFF) {
	        unsigned int s = htonl(payload_size);
	        
	        payload_head[1] = 127;
	        payload_head[2] = 0;
	        payload_head[3] = 0;
	        payload_head[4] = 0;
	        payload_head[5] = 0;
	        
            memcpy(&payload_head[6], &s, 4);

	        payload_length = 10;
	    }
        
        finish &= sendbin(client->fd, payload_head, payload_length, 0, g_ape);        
	}
	
	finish &= sendbin(client->fd, "[", 1, 0, g_ape);
	
	finish &= sendbin(client->fd, raw->data, raw->len, 0, g_ape);
	
	finish &= sendbin(client->fd, "]", 1, 0, g_ape);
	
	if (properties != NULL && properties->padding.right.val != NULL) {
		finish &= sendbin(client->fd, properties->padding.right.val, properties->padding.right.len, 0, g_ape);
	}
	
	free_raw(raw);
	
	return finish;
}
Пример #7
0
static void process_websocket_frame(ape_socket *co, acetables *g_ape)
{
    ape_buffer *buffer = &co->buffer_in;
    websocket_state *websocket = co->parser.data;
    ape_parser *parser = &co->parser;
    
    unsigned char *pData;
    
    for (pData = (unsigned char *)&buffer->data[websocket->offset]; websocket->offset < buffer->length; websocket->offset++, pData++) {
        switch(websocket->step) {
            case WS_STEP_KEY:
                /* Copy the xor key (32 bits) */
                websocket->key.val[websocket->key.pos] = *pData;
                if (++websocket->key.pos == 4) {
                    websocket->step = WS_STEP_DATA;
                }
                break;
            case WS_STEP_START:
                /* Contain fragmentaiton infos & opcode (+ reserved bits) */
                websocket->frame_payload.start = *pData;

                websocket->step = WS_STEP_LENGTH;
                break;
            case WS_STEP_LENGTH:
                /* Check for MASK bit */
                if (!(*pData & 0x80)) {
                    return;
                }
                switch (*pData & 0x7F) { /* 7bit length */
                    case 126:
                        /* Following 16bit are length */
                        websocket->step = WS_STEP_SHORT_LENGTH;
                        break;
                    case 127:
                        /* Following 64bit are length */
                        websocket->step = WS_STEP_EXTENDED_LENGTH;
                        break;
                    default:
                        /* We have the actual length */
                        websocket->frame_payload.extended_length = *pData & 0x7F;
                        websocket->step = WS_STEP_KEY;
                        break;
                }
                break;
            case WS_STEP_SHORT_LENGTH:
                memcpy(((char *)&websocket->frame_payload)+(websocket->frame_pos), 
                        pData, 1);
                if (websocket->frame_pos == 3) {
                    websocket->frame_payload.extended_length = ntohs(websocket->frame_payload.short_length);
                    websocket->step = WS_STEP_KEY;
                }
                break;
            case WS_STEP_EXTENDED_LENGTH:
                memcpy(((char *)&websocket->frame_payload)+(websocket->frame_pos),
                        pData, 1);
                if (websocket->frame_pos == 9) {
                    websocket->frame_payload.extended_length = ntohl(websocket->frame_payload.extended_length >> 32);
                    websocket->step = WS_STEP_KEY;
                }        
                break;
            case WS_STEP_DATA:
                if (websocket->data_pos == 0) {
                    websocket->data_pos = websocket->offset;
                }
                
                *pData ^= websocket->key.val[(websocket->frame_pos - websocket->data_pos) % 4];

                if (--websocket->frame_payload.extended_length == 0) {
                    unsigned char saved;
                    
                    websocket->data = &buffer->data[websocket->data_pos];
                    websocket->step = WS_STEP_START;
                    websocket->frame_pos = -1;
                    websocket->frame_payload.extended_length = 0;
                    websocket->data_pos = 0;
                    websocket->key.pos = 0;

                    switch(websocket->frame_payload.start & 0x0F) {
                        case 0x8:
                        {
                            /*
                              Close frame
                              Reply by a close response
                            */
                            char payload_head[2] = { 0x88, 0x00 };
                            sendbin(co->fd, payload_head, 2, 0, g_ape);
                            return;
                        }
                        case 0x9:
                        {
                            int body_length = &buffer->data[websocket->offset+1] - websocket->data;
                            char payload_head[2] = { 0x8a, body_length & 0x7F };
                            
                            /* All control frames MUST be 125 bytes or less */
                            if (body_length > 125) {
                                payload_head[0] = 0x88;
                                payload_head[1] = 0x00;      
                                sendbin(co->fd, payload_head, 2, 1, g_ape);
                                return;
                            }
                            PACK_TCP(co->fd);
                            sendbin(co->fd, payload_head, 2, 0, g_ape);
                            if (body_length) {
                                sendbin(co->fd, websocket->data, body_length, 0, g_ape);
                            }
                            FLUSH_TCP(co->fd);
                            break;
                        }
                        case 0xA: /* Never called as long as we never ask for pong */
                            break;
                        default:
                            /* Data frame */
                            saved = buffer->data[websocket->offset+1];
                            buffer->data[websocket->offset+1] = '\0';
                            parser->onready(parser, g_ape);
                            buffer->data[websocket->offset+1] = saved;                            
                            break;
                    }
                    
                    if (websocket->offset+1 == buffer->length) {
                        websocket->offset = 0;
                        buffer->length = 0;
                        websocket->frame_pos = 0;
                        websocket->key.pos = 0;
                        return;
                    }
                }
                break;
            default:
                break;
        }
        websocket->frame_pos++;
    }
Пример #8
0
unsigned int checkcmd(clientget *cget, subuser **iuser, acetables *g_ape)
{
	char *param[64+1], *cmd;
	callback *cmdback;
	
	size_t nTok;
	
	unsigned int flag;
	
	USERS *guser = NULL;
	subuser *sub = NULL;
	

	nTok = explode('&', cget->get, param, 64);
	
	if (nTok < 1) {
		cmd = NULL;
	} else {
		cmd = param[0];

	}
	
	/* TODO: Making a simple chainlist can be more efficient since we do not have many cmds */
	cmdback = (callback *)hashtbl_seek(g_ape->hCallback, cmd);
	if (cmdback != NULL) {
		if ((nTok-1) == cmdback->nParam || (cmdback->nParam < 0 && (nTok-1) >= (cmdback->nParam*-1) && (cmdback->nParam*-1) <= 16)) {
			int tmpfd = 0;
			callbackp cp;
			switch(cmdback->need) {
				case NEED_SESSID:
					guser = seek_user_id(param[1], g_ape);
					break;
				case NEED_NOTHING:
					guser = NULL;
					break;
			}
			
			if (cmdback->need != NEED_NOTHING) {
				if (guser == NULL) {
					SENDH(cget->fdclient, ERR_BAD_SESSID, g_ape);
					
					return (CONNECT_SHUTDOWN);
				} else {
					sub = getsubuser(guser, cget->host);
					if (sub != NULL && sub->fd != cget->fdclient && sub->state == ALIVE) {
						if (guser->transport == TRANSPORT_IFRAME) {
							/* iframe is already open on "sub" */
							tmpfd = sub->fd; /* Forward data directly to iframe */
							CLOSE(cget->fdclient, g_ape);
							shutdown(cget->fdclient, 2); /* Immediatly close controller */
						} else {
							/* Only one connection is allowed per user/host */
							CLOSE(sub->fd, g_ape);
							shutdown(sub->fd, 2);
							sub->state = ADIED;
							sub->fd = cget->fdclient;					
						}
					} else if (sub == NULL) {
						sub = addsubuser(cget->fdclient, cget->host, guser);
						if (sub != NULL) {
							subuser_restor(sub, g_ape);
						}
					} else if (sub != NULL) {
						sub->fd = cget->fdclient;
					}
					guser->idle = (long int)time(NULL); // update user idle

					sub->idle = guser->idle; // Update subuser idle
				}
			}
			cp.param = param;
			cp.fdclient = (tmpfd ? tmpfd : cget->fdclient);
			cp.call_user = guser,
			cp.g_ape = g_ape;
			cp.nParam = nTok-1;
			cp.host = cget->host;
			
			flag = cmdback->func(&cp);
			
			if (flag & FOR_NULL) {
				guser = NULL;
			} else if (flag & FOR_LOGIN) {
				guser = cp.call_user;
			} 
			
			if (guser != NULL) {

				if (sub == NULL && (sub = getsubuser(guser, cget->host)) == NULL) {
					
					if ((sub = addsubuser(cget->fdclient, cget->host, guser)) == NULL) {
						return (CONNECT_SHUTDOWN);
					}
					subuser_restor(sub, g_ape);
					
					if (guser->transport == TRANSPORT_IFRAME) {
						sendbin(sub->fd, HEADER, strlen(HEADER), g_ape);
					}			
				}

				*iuser = (tmpfd ? NULL : sub);
				
				if (flag & FOR_UPDATE_IP) {
					strncpy(guser->ip, cget->ip_get, 16);
				}
				
				/* If tmpfd is set, we do not have reasons to change this state */
				if (!tmpfd) {
					sub->state = ALIVE;
				}
				return (CONNECT_KEEPALIVE);
				
			}
			return (CONNECT_SHUTDOWN);
		} else {

			SENDH(cget->fdclient, ERR_BAD_PARAM, g_ape);
		}
	} else { // unregistered CMD
		SENDH(cget->fdclient, ERR_BAD_CMD, g_ape);
	}
	return (CONNECT_SHUTDOWN);
}
Пример #9
0
subuser *checkrecv(ape_socket *co, acetables *g_ape)
{
	unsigned int op;
	http_state *http = co->parser.data;
	subuser *user = NULL;
	clientget cget;
	
	if (http->host == NULL) {
		shutdown(co->fd, 2);
		return NULL;
	}
	
	if (gettransport(http->uri) == TRANSPORT_WEBSOCKET) {
		char *origin = get_header_line(http->hlines, "Origin");
		websocket_state *websocket;
		if (origin == NULL) {
			shutdown(co->fd, 2);
			return NULL;
		}
		
		PACK_TCP(co->fd);
		sendbin(co->fd, CONST_STR_LEN(WEBSOCKET_HARDCODED_HEADERS), 0, g_ape);
		sendbin(co->fd, CONST_STR_LEN("WebSocket-Origin: "), 0, g_ape);
		sendbin(co->fd, origin, strlen(origin), 0, g_ape);
		sendbin(co->fd, CONST_STR_LEN("\r\nWebSocket-Location: ws://"), 0, g_ape);
		sendbin(co->fd, http->host, strlen(http->host), 0, g_ape);
		sendbin(co->fd, http->uri, strlen(http->uri), 0, g_ape);
		sendbin(co->fd, CONST_STR_LEN("\r\n\r\n"), 0, g_ape);
		FLUSH_TCP(co->fd);
		
		co->parser = parser_init_stream(co);
		websocket = co->parser.data;
		websocket->http = http; /* keep http data */
		
		return NULL;
	}

	if (http->data == NULL) {
		sendbin(co->fd, HEADER_DEFAULT, HEADER_DEFAULT_LEN, 0, g_ape);
		sendbin(co->fd, CONST_STR_LEN(CONTENT_NOTFOUND), 0, g_ape);
		
		safe_shutdown(co->fd, g_ape);
		return NULL;
	}
	
	cget.client = co;
	cget.ip_get = co->ip_client;
	cget.get = http->data;
	cget.host = http->host;
	cget.hlines = http->hlines;
	
	op = checkcmd(&cget, gettransport(http->uri), &user, g_ape);

	switch (op) {
		case CONNECT_SHUTDOWN:
			safe_shutdown(co->fd, g_ape);			
			break;
		case CONNECT_KEEPALIVE:
			break;
	}
	
	return user;
}
Пример #10
0
int http_send_headers(http_headers_response *headers, const char *default_h, unsigned int default_len, ape_socket *client, acetables *g_ape)
{
	char code[4];
	int finish = 1;
	struct _http_headers_fields *fields;
	//HTTP/1.1 200 OK\r\n
	
	if (headers == NULL) {
		finish &= sendbin(client->fd, (char *)default_h, default_len, 0, g_ape);
	} else {
		/* We have a lot of write syscall here. TODO : use of writev */
		itos(headers->code, code, 4);
		finish &= sendbin(client->fd, "HTTP/1.1 ", 9, 0, g_ape);
		finish &= sendbin(client->fd, code, 3, 0, g_ape);
		finish &= sendbin(client->fd, " ", 1, 0, g_ape);
		finish &= sendbin(client->fd, headers->detail.val, headers->detail.len, 0, g_ape);
		finish &= sendbin(client->fd, "\r\n", 2, 0, g_ape);
	
		for (fields = headers->fields; fields != NULL; fields = fields->next) {
			finish &= sendbin(client->fd, fields->key.val, fields->key.len, 0, g_ape);
			finish &= sendbin(client->fd, ": ", 2, 0, g_ape);
			finish &= sendbin(client->fd, fields->value.val, fields->value.len, 0, g_ape);
			finish &= sendbin(client->fd, "\r\n", 2, 0, g_ape);
		
			fields = fields->next;
		}
	
		finish &= sendbin(client->fd, "\r\n", 2, 0, g_ape);
	}
	
	return finish;
}
Пример #11
0
void sendbmp() {
    printf("sending the bmp\n");
    sendconst(bmphdr); 	// Now Send a header
    sendbin(starshipbmp);//and the binary data!
}
Пример #12
0
void sendfavicon() {
    printf("sending the icon\n");
    sendconst(iconhdr); 	// Now Send a header
    sendbin(starshipicon);//and the binary data!
}