예제 #1
0
static char *builtin_function_checkmd5(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) 
{
	int argc;
	char *argv[2];
	char *args;
	char newmd5[33];

	if (!data || ast_strlen_zero(data)) {
		ast_log(LOG_WARNING, "Syntax: CHECK_MD5(<digest>,<data>) - missing argument!\n");
		return NULL;
	}

	args = ast_strdupa(data);	
	argc = ast_app_separate_args(args, '|', argv, sizeof(argv) / sizeof(argv[0]));

	if (argc < 2) {
		ast_log(LOG_WARNING, "Syntax: CHECK_MD5(<digest>,<data>) - missing argument!\n");
		return NULL;
	}

	ast_md5_hash(newmd5, argv[1]);

	if (!strcasecmp(newmd5, argv[0]))	/* they match */
		ast_copy_string(buf, "1", len);
	else
		ast_copy_string(buf, "0", len);
	
	return buf;
}
예제 #2
0
int ast_sip_location_add_contact_nolock(struct ast_sip_aor *aor, const char *uri,
		struct timeval expiration_time, const char *path_info, const char *user_agent,
		const char *via_addr, int via_port, const char *call_id,
		struct ast_sip_endpoint *endpoint)
{
	struct ast_sip_contact *contact;
	int res;
	char name[MAX_OBJECT_FIELD * 2 + 3];
	char hash[33];

	ast_md5_hash(hash, uri);
	snprintf(name, sizeof(name), "%s;@%s", ast_sorcery_object_get_id(aor), hash);

	contact = ast_sorcery_alloc(ast_sip_get_sorcery(), "contact", name);
	if (!contact) {
		return -1;
	}

	ast_string_field_set(contact, uri, uri);
	contact->expiration_time = expiration_time;
	contact->qualify_frequency = aor->qualify_frequency;
	contact->qualify_timeout = aor->qualify_timeout;
	contact->authenticate_qualify = aor->authenticate_qualify;
	if (path_info && aor->support_path) {
		ast_string_field_set(contact, path, path_info);
	}

	if (!ast_strlen_zero(aor->outbound_proxy)) {
		ast_string_field_set(contact, outbound_proxy, aor->outbound_proxy);
	}

	if (!ast_strlen_zero(user_agent)) {
		ast_string_field_set(contact, user_agent, user_agent);
	}

	if (!ast_strlen_zero(ast_config_AST_SYSTEM_NAME)) {
		ast_string_field_set(contact, reg_server, ast_config_AST_SYSTEM_NAME);
	}

	if (!ast_strlen_zero(via_addr)) {
		ast_string_field_set(contact, via_addr, via_addr);
	}
	contact->via_port = via_port;

	if (!ast_strlen_zero(call_id)) {
		ast_string_field_set(contact, call_id, call_id);
	}

	contact->endpoint = ao2_bump(endpoint);

	if (endpoint) {
		ast_string_field_set(contact, endpoint_name, ast_sorcery_object_get_id(endpoint));
	}

	res = ast_sorcery_create(ast_sip_get_sorcery(), contact);
	ao2_ref(contact, -1);
	return res;
}
예제 #3
0
/*! \brief Custom handler for permanent URIs */
static int permanent_uri_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
{
	struct ast_sip_aor *aor = obj;
	const char *aor_id = ast_sorcery_object_get_id(aor);
	char *contacts;
	char *contact_uri;

	if (ast_strlen_zero(var->value)) {
		return 0;
	}

	contacts = ast_strdupa(var->value);
	while ((contact_uri = ast_strip(strsep(&contacts, ",")))) {
		struct ast_sip_contact *contact;
		struct ast_sip_contact_status *status;
		char hash[33];
		char contact_id[strlen(aor_id) + sizeof(hash) + 2];

		if (ast_strlen_zero(contact_uri)) {
			continue;
		}

		if (ast_sip_validate_uri_length(contact_uri)) {
			ast_log(LOG_ERROR, "Contact uri or hostname length exceeds pjproject limit: %s\n", contact_uri);
			return -1;
		}

		if (!aor->permanent_contacts) {
			aor->permanent_contacts = ao2_container_alloc_list(AO2_ALLOC_OPT_LOCK_NOLOCK,
				AO2_CONTAINER_ALLOC_OPT_DUPS_REJECT, permanent_uri_sort_fn, NULL);
			if (!aor->permanent_contacts) {
				return -1;
			}
		}

		ast_md5_hash(hash, contact_uri);
		snprintf(contact_id, sizeof(contact_id), "%s@@%s", aor_id, hash);
		contact = ast_sorcery_alloc(ast_sip_get_sorcery(), "contact", contact_id);
		if (!contact) {
			return -1;
		}

		ast_string_field_set(contact, uri, contact_uri);

		status = ast_res_pjsip_find_or_create_contact_status(contact);
		if (!status) {
			ao2_ref(contact, -1);
			return -1;
		}
		ao2_ref(status, -1);

		ao2_link(aor->permanent_contacts, contact);
		ao2_ref(contact, -1);
	}

	return 0;
}
예제 #4
0
파일: func_md5.c 프로젝트: axiatp/asterisk
static int md5(struct ast_channel *chan, char *cmd, char *data,
	       char *buf, size_t len)
{
	if (ast_strlen_zero(data)) {
		ast_log(LOG_WARNING, "Syntax: MD5(<data>) - missing argument!\n");
		return -1;
	}

	ast_md5_hash(buf, data);
	buf[32] = '\0';

	return 0;
}
예제 #5
0
static char *builtin_function_md5(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) 
{
	char md5[33];

	if (ast_strlen_zero(data)) {
		ast_log(LOG_WARNING, "Syntax: MD5(<data>) - missing argument!\n");
		return NULL;
	}

	ast_md5_hash(md5, data);
	ast_copy_string(buf, md5, len);
	
	return buf;
}
/*!
 * \brief Calculate a nonce
 *
 * We use this in order to create authentication challenges. We also use this in order
 * to verify that an incoming request with credentials could be in response to one
 * of our challenges.
 *
 * The nonce is calculated from a timestamp, the source IP address, the source port, a
 * unique ID for us, and the realm. This helps to ensure that the incoming request
 * is from the same source that the nonce was calculated for. Including the realm
 * ensures that multiple challenges to the same request have different nonces.
 *
 * \param A UNIX timestamp expressed as a string
 * \param rdata The incoming request
 * \param realm The realm for which authentication should occur
 */
static int build_nonce(struct ast_str **nonce, const char *timestamp, const pjsip_rx_data *rdata, const char *realm)
{
	struct ast_str *str = ast_str_alloca(256);
	RAII_VAR(char *, eid, ao2_global_obj_ref(entity_id), ao2_cleanup);
	char hash[32];

	ast_str_append(&str, 0, "%s", timestamp);
	ast_str_append(&str, 0, ":%s", rdata->pkt_info.src_name);
	ast_str_append(&str, 0, ":%d", rdata->pkt_info.src_port);
	ast_str_append(&str, 0, ":%s", eid);
	ast_str_append(&str, 0, ":%s", realm);
	ast_md5_hash(hash, ast_str_buffer(str));

	ast_str_append(nonce, 0, "%s/%s", timestamp, hash);
	return 0;
}
예제 #7
0
파일: location.c 프로젝트: MakerHe/asterisk
int ast_sip_location_add_contact(struct ast_sip_aor *aor, const char *uri,
		struct timeval expiration_time, const char *path_info, const char *user_agent,
		struct ast_sip_endpoint *endpoint)
{
	char name[MAX_OBJECT_FIELD * 2 + 3];
	RAII_VAR(struct ast_sip_contact *, contact, NULL, ao2_cleanup);
	char hash[33];

	ast_md5_hash(hash, uri);
	snprintf(name, sizeof(name), "%s;@%s", ast_sorcery_object_get_id(aor), hash);

	if (!(contact = ast_sorcery_alloc(ast_sip_get_sorcery(), "contact", name))) {
		return -1;
	}

	ast_string_field_set(contact, uri, uri);
	contact->expiration_time = expiration_time;
	contact->qualify_frequency = aor->qualify_frequency;
	contact->qualify_timeout = aor->qualify_timeout;
	contact->authenticate_qualify = aor->authenticate_qualify;
	if (path_info && aor->support_path) {
		ast_string_field_set(contact, path, path_info);
	}

	if (!ast_strlen_zero(aor->outbound_proxy)) {
		ast_string_field_set(contact, outbound_proxy, aor->outbound_proxy);
	}

	if (!ast_strlen_zero(user_agent)) {
		ast_string_field_set(contact, user_agent, user_agent);
	}

	contact->endpoint = ao2_bump(endpoint);

	return ast_sorcery_create(ast_sip_get_sorcery(), contact);
}
static int auth_exec(struct ast_channel *chan, void *data)
{
	int res=0;
	int jump = 0;
	int retries;
	struct localuser *u;
	char password[256]="";
	char passwd[256];
	char *opts;
	char *prompt;
	
	if (ast_strlen_zero(data)) {
		ast_log(LOG_WARNING, "Authenticate requires an argument(password)\n");
		return -1;
	}
	
	LOCAL_USER_ADD(u);

	if (chan->_state != AST_STATE_UP) {
		res = ast_answer(chan);
		if (res) {
			LOCAL_USER_REMOVE(u);
			return -1;
		}
	}
	
	strncpy(password, data, sizeof(password) - 1);
	opts=strchr(password, '|');
	if (opts) {
		*opts = 0;
		opts++;
	} else
		opts = "";
	if (strchr(opts, 'j'))
		jump = 1;
	/* Start asking for password */
	prompt = "agent-pass";
	for (retries = 0; retries < 3; retries++) {
		res = ast_app_getdata(chan, prompt, passwd, sizeof(passwd) - 2, 0);
		if (res < 0)
			break;
		res = 0;
		if (password[0] == '/') {
			if (strchr(opts, 'd')) {
				char tmp[256];
				/* Compare against a database key */
				if (!ast_db_get(password + 1, passwd, tmp, sizeof(tmp))) {
					/* It's a good password */
					if (strchr(opts, 'r')) {
						ast_db_del(password + 1, passwd);
					}
					break;
				}
			} else {
				/* Compare against a file */
				FILE *f;
				f = fopen(password, "r");
				if (f) {
					char buf[256] = "";
					char md5passwd[33] = "";
					char *md5secret = NULL;

					while (!feof(f)) {
						fgets(buf, sizeof(buf), f);
						if (!feof(f) && !ast_strlen_zero(buf)) {
							buf[strlen(buf) - 1] = '\0';
							if (strchr(opts, 'm')) {
								md5secret = strchr(buf, ':');
								if (md5secret == NULL)
									continue;
								*md5secret = '\0';
								md5secret++;
								ast_md5_hash(md5passwd, passwd);
								if (!strcmp(md5passwd, md5secret)) {
									if (strchr(opts, 'a'))
										ast_cdr_setaccount(chan, buf);
									break;
								}
							} else {
								if (!strcmp(passwd, buf)) {
									if (strchr(opts, 'a'))
										ast_cdr_setaccount(chan, buf);
									break;
								}
							}
						}
					}
					fclose(f);
					if (!ast_strlen_zero(buf)) {
						if (strchr(opts, 'm')) {
							if (md5secret && !strcmp(md5passwd, md5secret))
								break;
						} else {
							if (!strcmp(passwd, buf))
								break;
						}
					}
				} else 
					ast_log(LOG_WARNING, "Unable to open file '%s' for authentication: %s\n", password, strerror(errno));
			}
		} else {
			/* Compare against a fixed password */
			if (!strcmp(passwd, password)) 
				break;
		}
		prompt="auth-incorrect";
	}
	if ((retries < 3) && !res) {
		if (strchr(opts, 'a') && !strchr(opts, 'm')) 
			ast_cdr_setaccount(chan, passwd);
		res = ast_streamfile(chan, "auth-thankyou", chan->language);
		if (!res)
			res = ast_waitstream(chan, "");
	} else {
		if (jump && ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101) == 0) {
			res = 0;
		} else {
			if (!ast_streamfile(chan, "vm-goodbye", chan->language))
				res = ast_waitstream(chan, "");
			res = -1;
		}
	}
	LOCAL_USER_REMOVE(u);
	return res;
}