From b2055f9364bdf454361c49771ff4869af44e5e79 Mon Sep 17 00:00:00 2001 From: jonl Date: Thu, 12 Jan 2012 17:41:58 +0100 Subject: [PATCH] Several changes: Parameter-changes to several nodes, stubs added, verification of remote domain to add_remote Added support for ?user=foo@bar.bz as supplement to ?username=foo&domain=bar to: user/get user/add_local user/add_remote user/remove user/change_pw user/update Added support for ?username=foo&domain=bar as supplement to ?user=foo@bar.bz to: phone/get Added support for ?alias=foo@bar.bz as supplement to ?alias_username=foo&alias_domain=bar to: alias/add alias/remove Added verification that user/add_remote is not done for local domains Added stub code for: user/check_pw user/update alias/list alias/list?destination[&e164] Removed alias/user, will implement this as alias/list?destination= Added vim swap-files to .gitignore --- .gitignore | 1 + alias.php | 88 ++++++++++++++++++++--- api-nodes.txt | 22 ++---- phone.php | 23 ++++-- user.php | 196 ++++++++++++++++++++++++++++++++++++++++++++------ 5 files changed, 277 insertions(+), 53 deletions(-) diff --git a/.gitignore b/.gitignore index 4f4773f..4018708 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ config.php +.*.swp diff --git a/alias.php b/alias.php index 398c12a..0c24b01 100644 --- a/alias.php +++ b/alias.php @@ -23,15 +23,69 @@ if ( !$config['sql_link'] ) switch ( $_SERVER['PATH_INFO'] ) { case "/list": + /* + Required parameters should be... + destination + */ + $dest_username = ""; + $dest_domain = ""; + $e164_only = false; + if ( array_key_exists( 'destination', $_GET) ) + { + $tmp = split_sipaddress($_GET['destination']); + if ( !$tmp ) + { + print json_encode ( array( 'response' => 'failed', 'cause' => 'invalid', 'detail' => 'Invalid SIP address') ); + break; + } + list ( $dest_username, $dest_domain ) = $tmp; + + if ( array_key_exists( 'e164', $_GET ) ) + { + if ( strtolower($_GET['e164']) == "true" ) $e164_only = true; + } + // TODO: Well. Code. This is a stub + + print json_encode ( array( 'response' => 'failed', 'cause' => 'notimplemented', 'detail' => 'Requested feature valid, but not implemented' ) ); + } + else if ( array_key_exists( 'alias', $_GET) ) + { + $tmp = split_sipaddress($_GET['alias']); + if ( !$tmp ) + { + print json_encode ( array( 'response' => 'failed', 'cause' => 'invalid', 'detail' => 'Invalid SIP address') ); + break; + } + list ( $alias_username, $alias_domain ) = $tmp; + + // TODO: Well. Code. This is a stub + + print json_encode ( array( 'response' => 'failed', 'cause' => 'notimplemented', 'detail' => 'Requested feature valid, but not implemented' ) ); + } + else + print json_encode( array( 'response' => 'invalid', 'cause' => 'parameters' ) ); break; case "/add": if ( array_key_exists( 'destination', $_GET) - //&& array_key_exists( 'domain', $_GET ) - && array_key_exists( 'alias_username', $_GET ) - && array_key_exists( 'alias_domain', $_GET ) ) + && ( ( array_key_exists( 'alias_username', $_GET) && array_key_exists( 'alias_domain', $_GET ) ) || array_key_exists('alias', $_GET) ) ) { - $alias_username = $_GET['alias_username']; - $alias_domain = $_GET['alias_domain']; + $alias_username = ""; + $alias_domain = ""; + if ( array_key_exists('alias_username', $_GET) ) + { + $alias_username = $_GET['alias_username']; + $alias_domain = $_GET['alias_domain']; + } + else + { + $alias = split_sipaddress($_GET['alias']); + if ( !$alias ) + { + print json_encode ( array( 'response' => 'failed', 'cause' => 'invalid', 'detail' => 'Invalid SIP address') ); + break; + } + list ( $alias_username, $alias_domain ) = $alias; + } if ( !verify_sipadress($_GET['destination']) ) { @@ -46,6 +100,8 @@ if ( !$config['sql_link'] ) break; } + // TODO: Verify that alias does not collide with existing SIP-adress + list ( $dest_username, $dest_domain ) = split_sipaddress( $_GET['destination']); if ( (!$dest_username)||(!$dest_domain)) @@ -98,11 +154,25 @@ if ( !$config['sql_link'] ) } break; case "/remove": - if ( array_key_exists( 'alias_username', $_GET ) - && array_key_exists( 'alias_domain', $_GET ) ) + if ( ( array_key_exists( 'alias_username', $_GET) && array_key_exists( 'alias_domain', $_GET ) ) || array_key_exists('alias', $_GET) ) { - $alias_username = $_GET['alias_username']; - $alias_domain = $_GET['alias_domain']; + $alias_username = ""; + $alias_domain = ""; + if ( array_key_exists('alias_username', $_GET) ) + { + $alias_username = $_GET['alias_username']; + $alias_domain = $_GET['alias_domain']; + } + else + { + $alias = split_sipaddress($_GET['alias']); + if ( !$alias ) + { + print json_encode ( array( 'response' => 'failed', 'cause' => 'invalid', 'detail' => 'Invalid SIP address') ); + break; + } + list ( $alias_username, $alias_domain ) = $alias; + } if ( !verify_sipadress( $alias_username . "@" . $alias_domain) ) { diff --git a/api-nodes.txt b/api-nodes.txt index 376beb1..a82e3c2 100644 --- a/api-nodes.txt +++ b/api-nodes.txt @@ -33,6 +33,7 @@ user/add_remote?username=foo&domain=bar&password=S3cr3t&displayname=baz®istra Adds a provisioning user for a remote SIP account. This allows locally provisioned hardphones to be associated with non-local SIP accounts. Returns a full user object, the same form as user/get + Returns 'failed' with 'cause' = 'domain' if an attempt is made to add_remote for a local domain. user/remove?username=foo&domain=bar Removes user account from Kamailio, if present, and removes user from provisioning. @@ -111,12 +112,10 @@ numbers/inpool?number=%2B4761123456 Returns 'response' = 'ok' with 'number' = '' If the number is in the pool Returns response = 'failed' with 'cause' = 'nonexistant' if not. - alias/list - Currently not implemented. - -alias/user?destination=foo@bar.bz -alias/user?destination=foo@bar.bz&e164=true +alias/list?destination=foo@bar.bz +alias/list?destination=foo@bar.bz&e164=true +alias/list?alias=foo@bar.bz Currently not implemented alias/add?alias_username=foo&alias_domain=bar.bz&destination=bar@qux.zx @@ -153,16 +152,7 @@ Planned, but not implemented nodes/functions: alias/list alias/user?destination=foo@bar.bz -Parameter updates: - Update nodes where username=foo&domain=bar.bz is used, to also support user=foo@bar.bz - user/get - user/add_local - user/add_remote - user/remove - user/change_pw - user/update - phone/get (reverse, needs username & domain param) - alias/add - alias/remove +Add collision prevention for aliases, make sure that no alias can be added when the alias +address would overlap/collide with a valid user-address authentication-mechanism :) diff --git a/phone.php b/phone.php index 11dd6db..9437d66 100644 --- a/phone.php +++ b/phone.php @@ -35,15 +35,26 @@ if ( !$config['sql_link'] ) } else print json_encode( array ( 'response' => 'failed', 'cause' => 'nonexistant', 'detail' => 'No results.')); } - else if ( array_key_exists( 'user', $_GET ) ) + else if ( ( array_key_exists( 'username', $_GET) && array_key_exists( 'domain', $_GET ) ) || array_key_exists('user', $_GET) ) { - $user = split_sipaddress($_GET['user']); - if (! $user ) + $username = ""; + $domain = ""; + if ( array_key_exists('username', $_GET) ) { - print json_encode ( array( 'response' => 'failed', 'cause' => 'nonexistant', 'detail' => 'Invalid SIP address') ); - break; + $username = $_GET['username']; + $domain = $_GET['domain']; } - list ( $username, $domain ) = $user; + else + { + $user = split_sipaddress($_GET['user']); + if ( !$user ) + { + print json_encode ( array( 'response' => 'failed', 'cause' => 'invalid', 'detail' => 'Invalid SIP address') ); + break; + } + list ( $username, $domain ) = $user; + } + $userdata = get_user_phones( $username, $domain ); if ( $userdata ) { diff --git a/user.php b/user.php index ca15955..f4ca316 100644 --- a/user.php +++ b/user.php @@ -25,10 +25,28 @@ if ( !$config['sql_link'] ) // Required GET parameters: // user: authentication username, SIP-username without domain component // domain: Domain/realm of the user. username + '@' + domain == SIP address. - if ( array_key_exists( 'username', $_GET) && array_key_exists( 'domain', $_GET ) ) + + if ( array_key_exists('user', $_GET) || + ( array_key_exists('username', $_GET) && array_key_exists('domain', $_GET ))) { - $username = $_GET['username']; - $domain = $_GET['domain']; + $username = ""; + $domain = ""; + if ( array_key_exists('username', $_GET) ) + { + $username = $_GET['username']; + $domain = $_GET['domain']; + } + else + { + $user = split_sipaddress($_GET['user']); + if ( !$user ) + { + print json_encode ( array( 'response' => 'failed', 'cause' => 'invalid', 'detail' => 'Invalid SIP address') ); + break; + } + list ( $username, $domain ) = $user; + } + // Now, do funky stuff. /* Test if user exists in both 'kamailio.subscribers' and 'provision.users' @@ -75,8 +93,7 @@ if ( !$config['sql_link'] ) /* What to do?? Required parameters should be... - username - domain + ( username & domain ) | user displayname email @@ -103,13 +120,29 @@ if ( !$config['sql_link'] ) */ // Test required parameters: - if ( array_key_exists( 'username', $_GET) - && array_key_exists( 'domain', $_GET ) + if ( + ( ( array_key_exists( 'username', $_GET) && array_key_exists( 'domain', $_GET ) ) || array_key_exists('user', $_GET) ) && array_key_exists( 'displayname', $_GET ) && array_key_exists( 'email', $_GET ) ) { - $username = $_GET['username']; - $domain = $_GET['domain']; + $username = ""; + $domain = ""; + if ( array_key_exists('username', $_GET) ) + { + $username = $_GET['username']; + $domain = $_GET['domain']; + } + else + { + $user = split_sipaddress($_GET['user']); + if ( !$user ) + { + print json_encode ( array( 'response' => 'failed', 'cause' => 'invalid', 'detail' => 'Invalid SIP address') ); + break; + } + list ( $username, $domain ) = $user; + } + $password = generate_password(); $displayname = $_GET['displayname']; $email = $_GET['email']; @@ -177,10 +210,9 @@ if ( !$config['sql_link'] ) case "/add_remote": /* Required parameters should be... - username - password - domain + ( username & domain ) | user displayname + password registrar Optional parameters r_port @@ -190,6 +222,7 @@ if ( !$config['sql_link'] ) dialplan linetext + Verify that the domain is not a local kamailio domain (REMOTE user..) Verify that the username+domain is not already registered in 'provision.users'. * If r_port is empty, set to 5060 * If proxy/port is empty, set to registrar/port @@ -214,15 +247,31 @@ if ( !$config['sql_link'] ) // Test required parameters: - if ( array_key_exists( 'username', $_GET) - && array_key_exists( 'password', $_GET ) + if ( + ( ( array_key_exists( 'username', $_GET) && array_key_exists( 'domain', $_GET ) ) || array_key_exists('user', $_GET) ) && array_key_exists( 'displayname', $_GET ) - && array_key_exists( 'domain', $_GET ) + && array_key_exists( 'password', $_GET ) && array_key_exists( 'registrar', $_GET ) ) { - $username = $_GET['username']; + $username = ""; + $domain = ""; + if ( array_key_exists('username', $_GET) ) + { + $username = $_GET['username']; + $domain = $_GET['domain']; + } + else + { + $user = split_sipaddress($_GET['user']); + if ( !$user ) + { + print json_encode ( array( 'response' => 'failed', 'cause' => 'invalid', 'detail' => 'Invalid SIP address') ); + break; + } + list ( $username, $domain ) = $user; + } + $password = $_GET['password']; - $domain = $_GET['domain']; $displayname = $_GET['displayname']; $registrar = $_GET['registrar']; $r_port = ( array_key_exists('r_port', $_GET) ) ? $_GET['r_port'] : 5060; @@ -233,6 +282,12 @@ if ( !$config['sql_link'] ) $dialplan = ( array_key_exists('dialplan', $_GET) ) ? $_GET['dialplan'] : $config['standard_dialplan']; $linetext = ( array_key_exists('linetext', $_GET) ) ? $_GET['linetext'] : $username . '@' . $domain; + if ( is_kamailio_domain( $domain ) ) + { + print json_encode ( array( 'response' => 'failed', 'cause' => 'domain', 'detail' => 'The selected domain is local, cannot add remote user' )); + break; + } + if ( is_provision_user ( $username, $domain ) ) { print json_encode ( array( 'response' => 'failed', 'cause' => 'exists', 'detail' => 'User already exists in provisioning configuration' )); @@ -268,8 +323,7 @@ if ( !$config['sql_link'] ) case "/remove": /* Required parameters should be... - username - domain + ( username & domain ) | user * Verify that no associations/relations exist in 'provision.phones' * Verify that the user exists in 'provision.users' @@ -283,10 +337,28 @@ if ( !$config['sql_link'] ) * If no such user exists, return 'response' => 'failed' with 'cause' => 'nonexistant' * On other failures, return 'response' => 'failed' with 'cause' => 'error' (may set 'detail' => 'message') */ - if ( array_key_exists( 'username', $_GET) && array_key_exists( 'domain', $_GET ) ) + if ( ( array_key_exists( 'username', $_GET) && array_key_exists( 'domain', $_GET ) ) + || array_key_exists('user', $_GET) ) + { - $username = $_GET['username']; - $domain = $_GET['domain']; + $username = ""; + $domain = ""; + if ( array_key_exists('username', $_GET) ) + { + $username = $_GET['username']; + $domain = $_GET['domain']; + } + else + { + $user = split_sipaddress($_GET['user']); + if ( !$user ) + { + print json_encode ( array( 'response' => 'failed', 'cause' => 'invalid', 'detail' => 'Invalid SIP address') ); + break; + } + list ( $username, $domain ) = $user; + } + if ( get_user_phones ( $username, $domain ) ) { print json_encode( array( 'response' => 'failed', 'cause' => 'inuse', 'detail' => 'User has associated provisioning. Remove and retry.' ) ); @@ -308,6 +380,86 @@ if ( !$config['sql_link'] ) break; } + print json_encode ( array( 'response' => 'invalid') ); + break; + case "/change_pw": + /* + Required parameters should be... + ( username & domain ) | user + + * Verify that no associations/relations exist in 'provision.phones' + * Verify that the user exists ... + * Test to see of user exists in 'provision.users' + * Test to see of user exists in 'kamailio.subscriber'. + * If no such user exists, return 'response' => 'failed' with 'cause' => 'nonexistant' + * Update user passwords in 'provision' and 'kamailio' as appropriate + * On other failures, return 'response' => 'failed' with 'cause' => 'error' (may set 'detail' => 'message') + */ + if ( ( array_key_exists( 'username', $_GET) && array_key_exists( 'domain', $_GET ) ) + || array_key_exists('user', $_GET) ) + + { + $username = ""; + $domain = ""; + if ( array_key_exists('username', $_GET) ) + { + $username = $_GET['username']; + $domain = $_GET['domain']; + } + else + { + $user = split_sipaddress($_GET['user']); + if ( !$user ) + { + print json_encode ( array( 'response' => 'failed', 'cause' => 'invalid', 'detail' => 'Invalid SIP address') ); + break; + } + list ( $username, $domain ) = $user; + } + print json_encode ( array( 'response' => 'failed', 'cause' => 'notimplemented', 'detail' => 'Requested feature valid, but not implemented' ) ); + } + else + print json_encode( array( 'response' => 'invalid', 'cause' => 'parameters' ) ); + break; + + case "/update": + /* + Required parameters should be... + ( username & domain ) | user + + * Verify that no associations/relations exist in 'provision.phones' + * Verify that the user exists ... + * Test to see of user exists in 'provision.users' + * Test to see of user exists in 'kamailio.subscriber'. + * If no such user exists, return 'response' => 'failed' with 'cause' => 'nonexistant' + * Get update parameters, and change as appropriate ;) + * On other failures, return 'response' => 'failed' with 'cause' => 'error' (may set 'detail' => 'message') + */ + if ( ( array_key_exists( 'username', $_GET) && array_key_exists( 'domain', $_GET ) ) + || array_key_exists('user', $_GET) ) + + { + $username = ""; + $domain = ""; + if ( array_key_exists('username', $_GET) ) + { + $username = $_GET['username']; + $domain = $_GET['domain']; + } + else + { + $user = split_sipaddress($_GET['user']); + if ( !$user ) + { + print json_encode ( array( 'response' => 'failed', 'cause' => 'invalid', 'detail' => 'Invalid SIP address') ); + break; + } + list ( $username, $domain ) = $user; + } + print json_encode ( array( 'response' => 'failed', 'cause' => 'notimplemented', 'detail' => 'Requested feature valid, but not implemented' ) ); + } + else + print json_encode( array( 'response' => 'invalid', 'cause' => 'parameters' ) ); break; case "/gen_pw": print generate_password(); -- 2.39.2