From babc0983e84970444cf2dc57e7ef6ee14e0802af Mon Sep 17 00:00:00 2001 From: "Michael L. Young" Date: Wed, 20 Jun 2012 03:18:50 +0000 Subject: [PATCH] Add IPv6 Support To Manager This patch adds IPv6 support to AMI. (Closes issue ASTERISK-19965) Reported by: Michael L. Young Tested by: Michael L. Young Patches: ami_ipv6_v3.diff uploaded by Michael L. Young (license 5026) Review: https://reviewboard.asterisk.org/r/1968/ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@369126 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- CHANGES | 2 + main/manager.c | 205 +++++++++++++++++++++++-------------------------- 2 files changed, 96 insertions(+), 111 deletions(-) diff --git a/CHANGES b/CHANGES index 61ea78bdc2..782b37de93 100644 --- a/CHANGES +++ b/CHANGES @@ -200,6 +200,8 @@ AMI (Asterisk Manager Interface) changes behavior to hanging up a single channel is unchanged, but if you pass a regex, the manager will send you a list of channels back that were hung up. + * Support for IPv6 addresses has been added. + FAX changes ----------- * FAXOPT(faxdetect) will enable a generic fax detect framehook for dialplan diff --git a/main/manager.c b/main/manager.c index 588d880e01..c7ff32e64e 100644 --- a/main/manager.c +++ b/main/manager.c @@ -1018,7 +1018,7 @@ static const struct { */ struct mansession_session { /*! \todo XXX need to document which fields it is protecting */ - struct sockaddr_in sin; /*!< address we are connecting from */ + struct ast_sockaddr addr; /*!< address we are connecting from */ FILE *f; /*!< fdopen() on the underlying fd */ int fd; /*!< descriptor used for output. Either the socket (AMI) or a temporary file (HTTP) */ int inuse; /*!< number of HTTP sessions using this entry */ @@ -1395,7 +1395,7 @@ static void session_destructor(void *obj) } /*! \brief Allocate manager session structure and add it to the list of sessions */ -static struct mansession_session *build_mansession(struct sockaddr_in sin) +static struct mansession_session *build_mansession(const struct ast_sockaddr *addr) { struct mansession_session *newsession; @@ -1417,7 +1417,7 @@ static struct mansession_session *build_mansession(struct sockaddr_in sin) newsession->waiting_thread = AST_PTHREADT_NULL; newsession->writetimeout = 100; newsession->send_events = -1; - newsession->sin = sin; + ast_sockaddr_copy(&newsession->addr, addr); ao2_link(sessions, newsession); @@ -1728,8 +1728,8 @@ static char *handle_showmanconn(struct ast_cli_entry *e, int cmd, struct ast_cli { struct mansession_session *session; time_t now = time(NULL); -#define HSMCONN_FORMAT1 " %-15.15s %-15.15s %-10.10s %-10.10s %-8.8s %-8.8s %-5.5s %-5.5s\n" -#define HSMCONN_FORMAT2 " %-15.15s %-15.15s %-10d %-10d %-8d %-8d %-5.5d %-5.5d\n" +#define HSMCONN_FORMAT1 " %-15.15s %-55.55s %-10.10s %-10.10s %-8.8s %-8.8s %-5.5s %-5.5s\n" +#define HSMCONN_FORMAT2 " %-15.15s %-55.55s %-10d %-10d %-8d %-8d %-5.5d %-5.5d\n" int count = 0; struct ao2_iterator i; @@ -1750,7 +1750,7 @@ static char *handle_showmanconn(struct ast_cli_entry *e, int cmd, struct ast_cli i = ao2_iterator_init(sessions, 0); while ((session = ao2_iterator_next(&i))) { ao2_lock(session); - ast_cli(a->fd, HSMCONN_FORMAT2, session->username, ast_inet_ntoa(session->sin.sin_addr), (int)(session->sessionstart), (int)(now - session->sessionstart), session->fd, session->inuse, session->readperm, session->writeperm); + ast_cli(a->fd, HSMCONN_FORMAT2, session->username, ast_sockaddr_stringify_addr(&session->addr), (int)(session->sessionstart), (int)(now - session->sessionstart), session->fd, session->inuse, session->readperm, session->writeperm); count++; ao2_unlock(session); unref_mansession(session); @@ -2211,7 +2211,6 @@ static enum ast_security_event_transport_type mansession_get_transport(const str static void report_invalid_user(const struct mansession *s, const char *username) { - struct ast_sockaddr addr_remote; char session_id[32]; struct ast_security_event_inval_acct_id inval_acct_id = { .common.event_type = AST_SECURITY_EVENT_INVAL_ACCT_ID, @@ -2224,14 +2223,12 @@ static void report_invalid_user(const struct mansession *s, const char *username .transport = mansession_get_transport(s), }, .common.remote_addr = { - .addr = &addr_remote, + .addr = &s->session->addr, .transport = mansession_get_transport(s), }, .common.session_id = session_id, }; - ast_sockaddr_from_sin(&addr_remote, &s->session->sin); - snprintf(session_id, sizeof(session_id), "%p", s); ast_security_event_report(AST_SEC_EVT(&inval_acct_id)); @@ -2239,7 +2236,6 @@ static void report_invalid_user(const struct mansession *s, const char *username static void report_failed_acl(const struct mansession *s, const char *username) { - struct ast_sockaddr addr_remote; char session_id[32]; struct ast_security_event_failed_acl failed_acl_event = { .common.event_type = AST_SECURITY_EVENT_FAILED_ACL, @@ -2252,14 +2248,12 @@ static void report_failed_acl(const struct mansession *s, const char *username) .transport = mansession_get_transport(s), }, .common.remote_addr = { - .addr = &addr_remote, + .addr = &s->session->addr, .transport = mansession_get_transport(s), }, .common.session_id = session_id, }; - ast_sockaddr_from_sin(&addr_remote, &s->session->sin); - snprintf(session_id, sizeof(session_id), "%p", s->session); ast_security_event_report(AST_SEC_EVT(&failed_acl_event)); @@ -2267,7 +2261,6 @@ static void report_failed_acl(const struct mansession *s, const char *username) static void report_inval_password(const struct mansession *s, const char *username) { - struct ast_sockaddr addr_remote; char session_id[32]; struct ast_security_event_inval_password inval_password = { .common.event_type = AST_SECURITY_EVENT_INVAL_PASSWORD, @@ -2280,14 +2273,12 @@ static void report_inval_password(const struct mansession *s, const char *userna .transport = mansession_get_transport(s), }, .common.remote_addr = { - .addr = &addr_remote, + .addr = &s->session->addr, .transport = mansession_get_transport(s), }, .common.session_id = session_id, }; - ast_sockaddr_from_sin(&addr_remote, &s->session->sin); - snprintf(session_id, sizeof(session_id), "%p", s->session); ast_security_event_report(AST_SEC_EVT(&inval_password)); @@ -2295,7 +2286,6 @@ static void report_inval_password(const struct mansession *s, const char *userna static void report_auth_success(const struct mansession *s) { - struct ast_sockaddr addr_remote; char session_id[32]; struct ast_security_event_successful_auth successful_auth = { .common.event_type = AST_SECURITY_EVENT_SUCCESSFUL_AUTH, @@ -2308,14 +2298,12 @@ static void report_auth_success(const struct mansession *s) .transport = mansession_get_transport(s), }, .common.remote_addr = { - .addr = &addr_remote, + .addr = &s->session->addr, .transport = mansession_get_transport(s), }, .common.session_id = session_id, }; - ast_sockaddr_from_sin(&addr_remote, &s->session->sin); - snprintf(session_id, sizeof(session_id), "%p", s->session); ast_security_event_report(AST_SEC_EVT(&successful_auth)); @@ -2323,7 +2311,6 @@ static void report_auth_success(const struct mansession *s) static void report_req_not_allowed(const struct mansession *s, const char *action) { - struct ast_sockaddr addr_remote; char session_id[32]; char request_type[64]; struct ast_security_event_req_not_allowed req_not_allowed = { @@ -2337,7 +2324,7 @@ static void report_req_not_allowed(const struct mansession *s, const char *actio .transport = mansession_get_transport(s), }, .common.remote_addr = { - .addr = &addr_remote, + .addr = &s->session->addr, .transport = mansession_get_transport(s), }, .common.session_id = session_id, @@ -2345,8 +2332,6 @@ static void report_req_not_allowed(const struct mansession *s, const char *actio .request_type = request_type, }; - ast_sockaddr_from_sin(&addr_remote, &s->session->sin); - snprintf(session_id, sizeof(session_id), "%p", s->session); snprintf(request_type, sizeof(request_type), "Action: %s", action); @@ -2355,7 +2340,6 @@ static void report_req_not_allowed(const struct mansession *s, const char *actio static void report_req_bad_format(const struct mansession *s, const char *action) { - struct ast_sockaddr addr_remote; char session_id[32]; char request_type[64]; struct ast_security_event_req_bad_format req_bad_format = { @@ -2369,7 +2353,7 @@ static void report_req_bad_format(const struct mansession *s, const char *action .transport = mansession_get_transport(s), }, .common.remote_addr = { - .addr = &addr_remote, + .addr = &s->session->addr, .transport = mansession_get_transport(s), }, .common.session_id = session_id, @@ -2377,8 +2361,6 @@ static void report_req_bad_format(const struct mansession *s, const char *action .request_type = request_type, }; - ast_sockaddr_from_sin(&addr_remote, &s->session->sin); - snprintf(session_id, sizeof(session_id), "%p", s->session); snprintf(request_type, sizeof(request_type), "Action: %s", action); @@ -2388,7 +2370,6 @@ static void report_req_bad_format(const struct mansession *s, const char *action static void report_failed_challenge_response(const struct mansession *s, const char *response, const char *expected_response) { - struct ast_sockaddr addr_remote; char session_id[32]; struct ast_security_event_chal_resp_failed chal_resp_failed = { .common.event_type = AST_SECURITY_EVENT_CHAL_RESP_FAILED, @@ -2401,7 +2382,7 @@ static void report_failed_challenge_response(const struct mansession *s, .transport = mansession_get_transport(s), }, .common.remote_addr = { - .addr = &addr_remote, + .addr = &s->session->addr, .transport = mansession_get_transport(s), }, .common.session_id = session_id, @@ -2411,8 +2392,6 @@ static void report_failed_challenge_response(const struct mansession *s, .expected_response = expected_response, }; - ast_sockaddr_from_sin(&addr_remote, &s->session->sin); - snprintf(session_id, sizeof(session_id), "%p", s->session); ast_security_event_report(AST_SEC_EVT(&chal_resp_failed)); @@ -2420,7 +2399,6 @@ static void report_failed_challenge_response(const struct mansession *s, static void report_session_limit(const struct mansession *s) { - struct ast_sockaddr addr_remote; char session_id[32]; struct ast_security_event_session_limit session_limit = { .common.event_type = AST_SECURITY_EVENT_SESSION_LIMIT, @@ -2433,14 +2411,12 @@ static void report_session_limit(const struct mansession *s) .transport = mansession_get_transport(s), }, .common.remote_addr = { - .addr = &addr_remote, + .addr = &s->session->addr, .transport = mansession_get_transport(s), }, .common.session_id = session_id, }; - ast_sockaddr_from_sin(&addr_remote, &s->session->sin); - snprintf(session_id, sizeof(session_id), "%p", s->session); ast_security_event_report(AST_SEC_EVT(&session_limit)); @@ -2461,7 +2437,6 @@ static int authenticate(struct mansession *s, const struct message *m) struct ast_manager_user *user = NULL; regex_t *regex_filter; struct ao2_iterator filter_iter; - struct ast_sockaddr addr; if (ast_strlen_zero(username)) { /* missing username */ return -1; @@ -2470,14 +2445,12 @@ static int authenticate(struct mansession *s, const struct message *m) /* locate user in locked state */ AST_RWLIST_WRLOCK(&users); - ast_sockaddr_from_sin(&addr, &s->session->sin); - if (!(user = get_manager_by_name_locked(username))) { report_invalid_user(s, username); - ast_log(LOG_NOTICE, "%s tried to authenticate with nonexistent user '%s'\n", ast_inet_ntoa(s->session->sin.sin_addr), username); - } else if (user->ha && !ast_apply_ha(user->ha, &addr)) { + ast_log(LOG_NOTICE, "%s tried to authenticate with nonexistent user '%s'\n", ast_sockaddr_stringify_addr(&s->session->addr), username); + } else if (user->ha && !ast_apply_ha(user->ha, &s->session->addr)) { report_failed_acl(s, username); - ast_log(LOG_NOTICE, "%s failed to pass IP ACL as '%s'\n", ast_inet_ntoa(s->session->sin.sin_addr), username); + ast_log(LOG_NOTICE, "%s failed to pass IP ACL as '%s'\n", ast_sockaddr_stringify_addr(&s->session->addr), username); } else if (!strcasecmp(astman_get_header(m, "AuthType"), "MD5")) { const char *key = astman_get_header(m, "Key"); if (!ast_strlen_zero(key) && !ast_strlen_zero(s->session->challenge) && user->secret) { @@ -2511,7 +2484,7 @@ static int authenticate(struct mansession *s, const struct message *m) } if (error) { - ast_log(LOG_NOTICE, "%s failed to authenticate as '%s'\n", ast_inet_ntoa(s->session->sin.sin_addr), username); + ast_log(LOG_NOTICE, "%s failed to authenticate as '%s'\n", ast_sockaddr_stringify_addr(&s->session->addr), username); AST_RWLIST_UNLOCK(&users); return -1; } @@ -3160,7 +3133,7 @@ static int action_login(struct mansession *s, const struct message *m) s->session->authenticated = 1; ast_atomic_fetchadd_int(&unauth_sessions, -1); if (manager_displayconnects(s->session)) { - ast_verb(2, "%sManager '%s' logged on from %s\n", (s->session->managerid ? "HTTP " : ""), s->session->username, ast_inet_ntoa(s->session->sin.sin_addr)); + ast_verb(2, "%sManager '%s' logged on from %s\n", (s->session->managerid ? "HTTP " : ""), s->session->username, ast_sockaddr_stringify_addr(&s->session->addr)); } astman_send_ack(s, m, "Authentication accepted"); if ((s->session->send_events & EVENT_FLAG_SYSTEM) @@ -3239,7 +3212,7 @@ static int action_hangup(struct mansession *s, const struct message *m) ast_verb(3, "%sManager '%s' from %s, hanging up channel: %s\n", (s->session->managerid ? "HTTP " : ""), s->session->username, - ast_inet_ntoa(s->session->sin.sin_addr), + ast_sockaddr_stringify_addr(&s->session->addr), ast_channel_name(c)); ast_channel_softhangup_withcause_locked(c, causecode); @@ -3285,7 +3258,7 @@ static int action_hangup(struct mansession *s, const struct message *m) ast_verb(3, "%sManager '%s' from %s, hanging up channel: %s\n", (s->session->managerid ? "HTTP " : ""), s->session->username, - ast_inet_ntoa(s->session->sin.sin_addr), + ast_sockaddr_stringify_addr(&s->session->addr), ast_channel_name(c)); ast_channel_softhangup_withcause_locked(c, causecode); @@ -5101,7 +5074,7 @@ static int get_input(struct mansession *s, char *output) } if (s->session->inlen >= maxlen) { /* no crlf found, and buffer full - sorry, too long for us */ - ast_log(LOG_WARNING, "Dumping long line with no return from %s: %s\n", ast_inet_ntoa(s->session->sin.sin_addr), src); + ast_log(LOG_WARNING, "Dumping long line with no return from %s: %s\n", ast_sockaddr_stringify_addr(&s->session->addr), src); s->session->inlen = 0; } res = 0; @@ -5196,7 +5169,7 @@ static int do_message(struct mansession *s) if (now - s->session->authstart > authtimeout) { if (displayconnects) { - ast_verb(2, "Client from %s, failed to authenticate in %d seconds\n", ast_inet_ntoa(s->session->sin.sin_addr), authtimeout); + ast_verb(2, "Client from %s, failed to authenticate in %d seconds\n", ast_sockaddr_stringify_addr(&s->session->addr), authtimeout); } res = -1; break; @@ -5257,7 +5230,7 @@ static void *session_do(void *data) }; int flags; int res; - struct sockaddr_in ser_remote_address_tmp; + struct ast_sockaddr ser_remote_address_tmp; struct protoent *p; if (ast_atomic_fetchadd_int(&unauth_sessions, +1) >= authlimit) { @@ -5266,8 +5239,8 @@ static void *session_do(void *data) goto done; } - ast_sockaddr_to_sin(&ser->remote_address, &ser_remote_address_tmp); - session = build_mansession(ser_remote_address_tmp); + ast_sockaddr_copy(&ser_remote_address_tmp, &ser->remote_address); + session = build_mansession(&ser_remote_address_tmp); if (session == NULL) { fclose(ser->f); @@ -5305,7 +5278,7 @@ static void *session_do(void *data) /* these fields duplicate those in the 'ser' structure */ session->fd = s.fd = ser->fd; session->f = s.f = ser->f; - session->sin = ser_remote_address_tmp; + ast_sockaddr_copy(&session->addr, &ser_remote_address_tmp); s.session = session; AST_LIST_HEAD_INIT_NOLOCK(&session->datastores); @@ -5328,12 +5301,12 @@ static void *session_do(void *data) /* session is over, explain why and terminate */ if (session->authenticated) { if (manager_displayconnects(session)) { - ast_verb(2, "Manager '%s' logged off from %s\n", session->username, ast_inet_ntoa(session->sin.sin_addr)); + ast_verb(2, "Manager '%s' logged off from %s\n", session->username, ast_sockaddr_stringify_addr(&session->addr)); } } else { ast_atomic_fetchadd_int(&unauth_sessions, -1); if (displayconnects) { - ast_verb(2, "Connect attempt from '%s' unable to authenticate\n", ast_inet_ntoa(session->sin.sin_addr)); + ast_verb(2, "Connect attempt from '%s' unable to authenticate\n", ast_sockaddr_stringify_addr(&session->addr)); } } @@ -5359,7 +5332,7 @@ static void purge_sessions(int n_max) if (session->sessiontimeout && (now > session->sessiontimeout) && !session->inuse) { if (session->authenticated && manager_displayconnects(session)) { ast_verb(2, "HTTP Manager '%s' timed out from %s\n", - session->username, ast_inet_ntoa(session->sin.sin_addr)); + session->username, ast_sockaddr_stringify_addr(&session->addr)); } ao2_unlock(session); session_destroy(session); @@ -6113,7 +6086,7 @@ static void process_output(struct mansession *s, struct ast_str **out, struct as static int generic_http_callback(struct ast_tcptls_session_instance *ser, enum ast_http_method method, enum output_format format, - struct sockaddr_in *remote_address, const char *uri, + const struct ast_sockaddr *remote_address, const char *uri, struct ast_variable *get_params, struct ast_variable *headers) { @@ -6150,14 +6123,11 @@ static int generic_http_callback(struct ast_tcptls_session_instance *ser, /* Create new session. * While it is not in the list we don't need any locking */ - if (!(session = build_mansession(*remote_address))) { + if (!(session = build_mansession(remote_address))) { ast_http_error(ser, 500, "Server Error", "Internal Server Error (out of memory)\n"); return -1; } ao2_lock(session); - session->sin = *remote_address; - session->fd = -1; - session->waiting_thread = AST_PTHREADT_NULL; session->send_events = 0; session->inuse = 1; /*!\note There is approximately a 1 in 1.8E19 chance that the following @@ -6215,11 +6185,11 @@ static int generic_http_callback(struct ast_tcptls_session_instance *ser, if (process_message(&s, &m)) { if (session->authenticated) { if (manager_displayconnects(session)) { - ast_verb(2, "HTTP Manager '%s' logged off from %s\n", session->username, ast_inet_ntoa(session->sin.sin_addr)); + ast_verb(2, "HTTP Manager '%s' logged off from %s\n", session->username, ast_sockaddr_stringify_addr(&session->addr)); } } else { if (displayconnects) { - ast_verb(2, "HTTP Connect attempt from '%s' unable to authenticate\n", ast_inet_ntoa(session->sin.sin_addr)); + ast_verb(2, "HTTP Connect attempt from '%s' unable to authenticate\n", ast_sockaddr_stringify_addr(&session->addr)); } } session->needdestroy = 1; @@ -6328,7 +6298,7 @@ generic_callback_out: static int auth_http_callback(struct ast_tcptls_session_instance *ser, enum ast_http_method method, enum output_format format, - struct sockaddr_in *remote_address, const char *uri, + const struct ast_sockaddr *remote_address, const char *uri, struct ast_variable *get_params, struct ast_variable *headers) { @@ -6354,7 +6324,6 @@ static int auth_http_callback(struct ast_tcptls_session_instance *ser, int u_writeperm; int u_writetimeout; int u_displayconnects; - struct ast_sockaddr addr; if (method != AST_HTTP_GET && method != AST_HTTP_HEAD && method != AST_HTTP_POST) { ast_http_error(ser, 501, "Not Implemented", "Attempt to use unimplemented / unsupported method"); @@ -6393,16 +6362,15 @@ static int auth_http_callback(struct ast_tcptls_session_instance *ser, user = get_manager_by_name_locked(d.username); if(!user) { AST_RWLIST_UNLOCK(&users); - ast_log(LOG_NOTICE, "%s tried to authenticate with nonexistent user '%s'\n", ast_inet_ntoa(remote_address->sin_addr), d.username); + ast_log(LOG_NOTICE, "%s tried to authenticate with nonexistent user '%s'\n", ast_sockaddr_stringify_addr(&session->addr), d.username); nonce = 0; goto out_401; } - ast_sockaddr_from_sin(&addr, remote_address); /* --- We have User for this auth, now check ACL */ - if (user->ha && !ast_apply_ha(user->ha, &addr)) { + if (user->ha && !ast_apply_ha(user->ha, remote_address)) { AST_RWLIST_UNLOCK(&users); - ast_log(LOG_NOTICE, "%s failed to pass IP ACL as '%s'\n", ast_inet_ntoa(remote_address->sin_addr), d.username); + ast_log(LOG_NOTICE, "%s failed to pass IP ACL as '%s'\n", ast_sockaddr_stringify_addr(&session->addr), d.username); ast_http_error(ser, 403, "Permission denied", "Permission denied\n"); return -1; } @@ -6452,7 +6420,7 @@ static int auth_http_callback(struct ast_tcptls_session_instance *ser, * Create new session. * While it is not in the list we don't need any locking */ - if (!(session = build_mansession(*remote_address))) { + if (!(session = build_mansession(remote_address))) { ast_http_error(ser, 500, "Server Error", "Internal Server Error (out of memory)\n"); return -1; } @@ -6468,7 +6436,7 @@ static int auth_http_callback(struct ast_tcptls_session_instance *ser, session->writetimeout = u_writetimeout; if (u_displayconnects) { - ast_verb(2, "HTTP Manager '%s' logged in from %s\n", session->username, ast_inet_ntoa(session->sin.sin_addr)); + ast_verb(2, "HTTP Manager '%s' logged in from %s\n", session->username, ast_sockaddr_stringify_addr(&session->addr)); } session->noncetime = session->sessionstart = time_now; session->authenticated = 1; @@ -6550,7 +6518,7 @@ static int auth_http_callback(struct ast_tcptls_session_instance *ser, if (process_message(&s, &m)) { if (u_displayconnects) { - ast_verb(2, "HTTP Manager '%s' logged off from %s\n", session->username, ast_inet_ntoa(session->sin.sin_addr)); + ast_verb(2, "HTTP Manager '%s' logged off from %s\n", session->username, ast_sockaddr_stringify_addr(&session->addr)); } session->needdestroy = 1; @@ -6641,33 +6609,33 @@ out_401: static int manager_http_callback(struct ast_tcptls_session_instance *ser, const struct ast_http_uri *urih, const char *uri, enum ast_http_method method, struct ast_variable *get_params, struct ast_variable *headers) { int retval; - struct sockaddr_in ser_remote_address_tmp; + struct ast_sockaddr ser_remote_address_tmp; - ast_sockaddr_to_sin(&ser->remote_address, &ser_remote_address_tmp); + ast_sockaddr_copy(&ser_remote_address_tmp, &ser->remote_address); retval = generic_http_callback(ser, method, FORMAT_HTML, &ser_remote_address_tmp, uri, get_params, headers); - ast_sockaddr_from_sin(&ser->remote_address, &ser_remote_address_tmp); + ast_sockaddr_copy(&ser->remote_address, &ser_remote_address_tmp); return retval; } static int mxml_http_callback(struct ast_tcptls_session_instance *ser, const struct ast_http_uri *urih, const char *uri, enum ast_http_method method, struct ast_variable *get_params, struct ast_variable *headers) { int retval; - struct sockaddr_in ser_remote_address_tmp; + struct ast_sockaddr ser_remote_address_tmp; - ast_sockaddr_to_sin(&ser->remote_address, &ser_remote_address_tmp); + ast_sockaddr_copy(&ser_remote_address_tmp, &ser->remote_address); retval = generic_http_callback(ser, method, FORMAT_XML, &ser_remote_address_tmp, uri, get_params, headers); - ast_sockaddr_from_sin(&ser->remote_address, &ser_remote_address_tmp); + ast_sockaddr_copy(&ser->remote_address, &ser_remote_address_tmp); return retval; } static int rawman_http_callback(struct ast_tcptls_session_instance *ser, const struct ast_http_uri *urih, const char *uri, enum ast_http_method method, struct ast_variable *get_params, struct ast_variable *headers) { int retval; - struct sockaddr_in ser_remote_address_tmp; + struct ast_sockaddr ser_remote_address_tmp; - ast_sockaddr_to_sin(&ser->remote_address, &ser_remote_address_tmp); + ast_sockaddr_copy(&ser_remote_address_tmp, &ser->remote_address); retval = generic_http_callback(ser, method, FORMAT_RAW, &ser_remote_address_tmp, uri, get_params, headers); - ast_sockaddr_from_sin(&ser->remote_address, &ser_remote_address_tmp); + ast_sockaddr_copy(&ser->remote_address, &ser_remote_address_tmp); return retval; } @@ -6700,33 +6668,33 @@ static struct ast_http_uri managerxmluri = { static int auth_manager_http_callback(struct ast_tcptls_session_instance *ser, const struct ast_http_uri *urih, const char *uri, enum ast_http_method method, struct ast_variable *get_params, struct ast_variable *headers) { int retval; - struct sockaddr_in ser_remote_address_tmp; + struct ast_sockaddr ser_remote_address_tmp; - ast_sockaddr_to_sin(&ser->remote_address, &ser_remote_address_tmp); + ast_sockaddr_copy(&ser_remote_address_tmp, &ser->remote_address); retval = auth_http_callback(ser, method, FORMAT_HTML, &ser_remote_address_tmp, uri, get_params, headers); - ast_sockaddr_from_sin(&ser->remote_address, &ser_remote_address_tmp); + ast_sockaddr_copy(&ser->remote_address, &ser_remote_address_tmp); return retval; } static int auth_mxml_http_callback(struct ast_tcptls_session_instance *ser, const struct ast_http_uri *urih, const char *uri, enum ast_http_method method, struct ast_variable *get_params, struct ast_variable *headers) { int retval; - struct sockaddr_in ser_remote_address_tmp; + struct ast_sockaddr ser_remote_address_tmp; - ast_sockaddr_to_sin(&ser->remote_address, &ser_remote_address_tmp); + ast_sockaddr_copy(&ser_remote_address_tmp, &ser->remote_address); retval = auth_http_callback(ser, method, FORMAT_XML, &ser_remote_address_tmp, uri, get_params, headers); - ast_sockaddr_from_sin(&ser->remote_address, &ser_remote_address_tmp); + ast_sockaddr_copy(&ser->remote_address, &ser_remote_address_tmp); return retval; } static int auth_rawman_http_callback(struct ast_tcptls_session_instance *ser, const struct ast_http_uri *urih, const char *uri, enum ast_http_method method, struct ast_variable *get_params, struct ast_variable *headers) { int retval; - struct sockaddr_in ser_remote_address_tmp; + struct ast_sockaddr ser_remote_address_tmp; - ast_sockaddr_to_sin(&ser->remote_address, &ser_remote_address_tmp); + ast_sockaddr_copy(&ser_remote_address_tmp, &ser->remote_address); retval = auth_http_callback(ser, method, FORMAT_RAW, &ser_remote_address_tmp, uri, get_params, headers); - ast_sockaddr_from_sin(&ser->remote_address, &ser_remote_address_tmp); + ast_sockaddr_copy(&ser->remote_address, &ser_remote_address_tmp); return retval; } @@ -6804,7 +6772,7 @@ static char *handle_manager_show_settings(struct ast_cli_entry *e, int cmd, stru case CLI_GENERATE: return NULL; } -#define FORMAT " %-25.25s %-15.15s\n" +#define FORMAT " %-25.25s %-15.55s\n" #define FORMAT2 " %-25.25s %-15d\n" if (a->argc != 3) { return CLI_SHOWUSAGE; @@ -6892,8 +6860,8 @@ static int __init_manager(int reload) struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 }; char a1[256]; char a1_hash[256]; - struct sockaddr_in ami_desc_local_address_tmp = { 0, }; - struct sockaddr_in amis_desc_local_address_tmp = { 0, }; + struct ast_sockaddr ami_desc_local_address_tmp; + struct ast_sockaddr amis_desc_local_address_tmp; int tls_was_enabled = 0; manager_enabled = 0; @@ -6962,10 +6930,8 @@ static int __init_manager(int reload) ast_sockaddr_setnull(&ami_desc.local_address); ast_sockaddr_setnull(&amis_desc.local_address); - ami_desc_local_address_tmp.sin_family = AF_INET; - amis_desc_local_address_tmp.sin_family = AF_INET; - - ami_desc_local_address_tmp.sin_port = htons(DEFAULT_MANAGER_PORT); + ast_sockaddr_parse(&ami_desc_local_address_tmp, "[::]", 0); + ast_sockaddr_set_port(&ami_desc_local_address_tmp, DEFAULT_MANAGER_PORT); tls_was_enabled = (reload && ami_tls_cfg.enabled); @@ -6999,13 +6965,26 @@ static int __init_manager(int reload) } else if (!strcasecmp(var->name, "webenabled")) { webmanager_enabled = ast_true(val); } else if (!strcasecmp(var->name, "port")) { - ami_desc_local_address_tmp.sin_port = htons(atoi(val)); + int bindport; + if (ast_parse_arg(val, PARSE_UINT32|PARSE_IN_RANGE, &bindport, 1024, 65535)) { + ast_log(LOG_WARNING, "Invalid port number '%s'\n", val); + } + ast_sockaddr_set_port(&ami_desc_local_address_tmp, bindport); } else if (!strcasecmp(var->name, "bindaddr")) { - if (!inet_aton(val, &ami_desc_local_address_tmp.sin_addr)) { - ast_log(LOG_WARNING, "Invalid address '%s' specified, using 0.0.0.0\n", val); - memset(&ami_desc_local_address_tmp.sin_addr, 0, - sizeof(ami_desc_local_address_tmp.sin_addr)); + /* remember port if it has already been set */ + int setport = ast_sockaddr_port(&ami_desc_local_address_tmp); + + if (ast_parse_arg(val, PARSE_ADDR|PARSE_PORT_IGNORE, NULL)) { + ast_log(LOG_WARNING, "Invalid address '%s' specified, default '%s' will be used\n", val, + ast_sockaddr_stringify_addr(&ami_desc_local_address_tmp)); + } else { + ast_sockaddr_parse(&ami_desc_local_address_tmp, val, PARSE_PORT_IGNORE); } + + if (setport) { + ast_sockaddr_set_port(&ami_desc_local_address_tmp, setport); + } + } else if (!strcasecmp(var->name, "brokeneventsaction")) { broken_events_action = ast_true(val); } else if (!strcasecmp(var->name, "allowmultiplelogin")) { @@ -7042,21 +7021,25 @@ static int __init_manager(int reload) } } - ast_sockaddr_to_sin(&amis_desc.local_address, &amis_desc_local_address_tmp); + ast_sockaddr_copy(&amis_desc_local_address_tmp, &amis_desc.local_address); /* if the amis address has not been set, default is the same as non secure ami */ - if (!amis_desc_local_address_tmp.sin_addr.s_addr) { - amis_desc_local_address_tmp.sin_addr = - ami_desc_local_address_tmp.sin_addr; + if (ast_sockaddr_isnull(&amis_desc_local_address_tmp)) { + ast_sockaddr_copy(&amis_desc_local_address_tmp, &ami_desc_local_address_tmp); } - if (!amis_desc_local_address_tmp.sin_port) { - amis_desc_local_address_tmp.sin_port = htons(DEFAULT_MANAGER_TLS_PORT); + /* if the amis address was not set, it will have non-secure ami port set; if + amis address was set, we need to check that a port was set or not, if not + use the default tls port */ + if (ast_sockaddr_port(&amis_desc_local_address_tmp) == 0 || + (ast_sockaddr_port(&ami_desc_local_address_tmp) == ast_sockaddr_port(&amis_desc_local_address_tmp))) { + + ast_sockaddr_set_port(&amis_desc_local_address_tmp, DEFAULT_MANAGER_TLS_PORT); } if (manager_enabled) { - ast_sockaddr_from_sin(&ami_desc.local_address, &ami_desc_local_address_tmp); - ast_sockaddr_from_sin(&amis_desc.local_address, &amis_desc_local_address_tmp); + ast_sockaddr_copy(&ami_desc.local_address, &ami_desc_local_address_tmp); + ast_sockaddr_copy(&amis_desc.local_address, &amis_desc_local_address_tmp); } AST_RWLIST_WRLOCK(&users);