Overview

Packages

  • admin
  • classes
    • media
  • CodeIgniter
    • Libraries
  • core
  • functions
  • JSMin
  • None
  • OpenID
  • PHP
  • PHPMailer
  • plugins
    • admin
    • development
    • feed
    • mail
    • media
    • misc
    • seo
    • spam
    • uploader
    • users
    • zenpage
    • zenphoto
      • news
  • Services
    • JSON

Classes

  • _zp_captcha
  • _zp_HTML_cache
  • admin_approval
  • Album
  • AlbumBase
  • AlbumZip
  • AMFReader
  • AMFStream
  • AnyFile
  • AnyFile_Options
  • Auth_OpenID
  • Auth_OpenID_AlreadySigned
  • Auth_OpenID_AssociateRequest
  • Auth_OpenID_Association
  • Auth_OpenID_AuthRequest
  • Auth_OpenID_AX
  • Auth_OpenID_AX_AttrInfo
  • Auth_OpenID_AX_Error
  • Auth_OpenID_AX_FetchRequest
  • Auth_OpenID_AX_FetchResponse
  • Auth_OpenID_AX_KeyValueMessage
  • Auth_OpenID_AX_Message
  • Auth_OpenID_AX_StoreRequest
  • Auth_OpenID_AX_StoreResponse
  • Auth_OpenID_BcMathWrapper
  • Auth_OpenID_CancelResponse
  • Auth_OpenID_CheckAuthRequest
  • Auth_OpenID_CheckIDRequest
  • Auth_OpenID_Consumer
  • Auth_OpenID_ConsumerResponse
  • Auth_OpenID_CryptUtil
  • Auth_OpenID_DatabaseConnection
  • Auth_OpenID_Decoder
  • Auth_OpenID_DiffieHellman
  • Auth_OpenID_DiffieHellmanSHA1ConsumerSession
  • Auth_OpenID_DiffieHellmanSHA1ServerSession
  • Auth_OpenID_DiffieHellmanSHA256ConsumerSession
  • Auth_OpenID_DiffieHellmanSHA256ServerSession
  • Auth_OpenID_DumbStore
  • Auth_OpenID_Encoder
  • Auth_OpenID_EncodingError
  • Auth_OpenID_Extension
  • Auth_OpenID_FailureResponse
  • Auth_OpenID_FileStore
  • Auth_OpenID_GenericConsumer
  • Auth_OpenID_GmpMathWrapper
  • Auth_OpenID_KVForm
  • Auth_OpenID_MalformedReturnURL
  • Auth_OpenID_MalformedTrustRoot
  • Auth_OpenID_Mapping
  • Auth_OpenID_MathLibrary
  • Auth_OpenID_MDB2Store
  • Auth_OpenID_MemcachedStore
  • Auth_OpenID_Message
  • Auth_OpenID_MySQLStore
  • Auth_OpenID_NamespaceMap
  • Auth_OpenID_NoReturnToError
  • Auth_OpenID_OpenIDStore
  • Auth_OpenID_PAPE_Request
  • Auth_OpenID_PAPE_Response
  • Auth_OpenID_Parse
  • Auth_OpenID_PlainTextConsumerSession
  • Auth_OpenID_PlainTextServerSession
  • Auth_OpenID_PostgreSQLStore
  • Auth_OpenID_Request
  • Auth_OpenID_Server
  • Auth_OpenID_ServerError
  • Auth_OpenID_ServerErrorContainer
  • Auth_OpenID_ServerRequest
  • Auth_OpenID_ServerResponse
  • Auth_OpenID_ServiceEndpoint
  • Auth_OpenID_ServiceEndpointLoader
  • Auth_OpenID_SessionNegotiator
  • Auth_OpenID_SetupNeededResponse
  • Auth_OpenID_Signatory
  • Auth_OpenID_SigningEncoder
  • Auth_OpenID_SQLiteStore
  • Auth_OpenID_SQLStore
  • Auth_OpenID_SRegBase
  • Auth_OpenID_SRegRequest
  • Auth_OpenID_SRegResponse
  • Auth_OpenID_SuccessResponse
  • Auth_OpenID_TrustRoot
  • Auth_OpenID_TypeURIMismatch
  • Auth_OpenID_UntrustedReturnURL
  • Auth_OpenID_WebResponse
  • Auth_Yadis_Discovery
  • Auth_Yadis_DiscoveryResult
  • Auth_Yadis_dom
  • Auth_Yadis_domxml
  • Auth_Yadis_HTTPFetcher
  • Auth_Yadis_HTTPResponse
  • Auth_Yadis_Manager
  • Auth_Yadis_ManagerLoader
  • Auth_Yadis_ParanoidHTTPFetcher
  • Auth_Yadis_ParseHTML
  • Auth_Yadis_PHPSession
  • Auth_Yadis_PlainHTTPFetcher
  • Auth_Yadis_ProxyResolver
  • Auth_Yadis_Service
  • Auth_Yadis_SessionLoader
  • Auth_Yadis_XMLParser
  • Auth_Yadis_XRDS
  • Auth_Yadis_Yadis
  • auto_backup
  • AVCSequenceParameterSetReader
  • bxslider
  • cacheManager
  • cacheManagerFeed
  • CI_jsmin
  • CI_load
  • cloneZenphoto
  • codeIgniter_kludge
  • colorbox
  • Comment
  • comment_form
  • contactformOptions
  • crop_image
  • cycle
  • defaultCodeblocks
  • deprecated_functions
  • DownloadList
  • dynamic_locale
  • dynamicAlbum
  • elFinder_options
  • email_new_user
  • exampleMacros
  • external_auth
  • ExternalFeed
  • externalFeed_options
  • favorites
  • favoritesOptions
  • federated_logon
  • feed
  • fieldExtender
  • flag_thumbnail
  • Gallery
  • galleryArticles
  • getID3
  • getid3_aac
  • getid3_apetag
  • getid3_flv
  • getid3_handler
  • getid3_id3v1
  • getid3_id3v2
  • getid3_lib
  • getid3_lyrics3
  • getid3_mp3
  • getid3_mpeg
  • getid3_quicktime
  • getid3_swf
  • GoogleMap
  • Googlemaps
  • googleVerifyOptions
  • hitcounter
  • HTML
  • htmlmetatags
  • http_auth
  • Image
  • image_effects
  • internal_deprecations
  • ipBlocker
  • jcarousel
  • jPlayer
  • jplayer_options
  • jquery_rating
  • JSMin
  • lib_GD_Options
  • lib_Imagick_Options
  • lib_NoGraphics
  • MediaObject
  • menu_manager
  • MergedRSS
  • MergedRSSOptions
  • mobile
  • Mobile_Detect
  • mobileTheme
  • multipleLayoutOptions
  • null_seo
  • OAuthConsumer
  • OAuthDataStore
  • OAuthRequest
  • OAuthServer
  • OAuthSignatureMethod
  • OAuthSignatureMethod_HMAC_SHA1
  • OAuthSignatureMethod_PLAINTEXT
  • OAuthSignatureMethod_RSA_SHA1
  • OAuthToken
  • OAuthUtil
  • pagedThumbsNav
  • pagedthumbsOptions
  • PclZip
  • PersistentObject
  • PHPMailer
  • PlainText
  • POP3
  • print_album_menu
  • pseudoPlayer
  • publishContent
  • quota_manager
  • reCaptcha
  • ReCaptchaResponse
  • register_user
  • rewriteRules
  • rewriteTokens
  • RSS
  • RSS_internal_deprecations
  • rss_options
  • search_statistics
  • SearchEngine
  • security_logger
  • seo_locale
  • Services_JSON
  • Services_JSON_Error
  • setupexternalFeed
  • setupRSS
  • show_not_loggedin
  • sitemap
  • slideshow
  • SMTP
  • static_html_cache
  • tagsuggest
  • TextObject
  • TextObject_internal_deprecations
  • TextObject_Options
  • ThemeObject
  • themeSwitcher
  • tinymce4Options
  • tinyURL
  • Transientimage
  • tweet
  • TwitterOAuth
  • UploadHandler
  • user_expiry
  • user_groups
  • user_logout_options
  • userAddressFields
  • utf8
  • Video
  • Video_internal_deprecations
  • VideoObject_Options
  • viewer_size_image_options
  • WEBdocs
  • WEBdocs_Options
  • xmpMetadata
  • Zenpage
  • Zenpage_internal_deprecations
  • ZenpageCategory
  • zenpagecms
  • ZenpageItems
  • ZenpageNews
  • ZenpagePage
  • ZenpageRoot
  • Zenphoto_Administrator
  • Zenphoto_Authority
  • zenphoto_org_news
  • zenphoto_seo
  • zenphotoDonate
  • ZipStream
  • zp_PHPMailer
  • zpCaptcha
  • zpFunctions
  • zpLegacySpam
  • zpMutex
  • zpSimpleSpam
  • zpTrivialSpam

Exceptions

  • BadFunctionCallException
  • BadMethodCallException
  • Exception
  • getid3_exception
  • JSMin_UnterminatedCommentException
  • JSMin_UnterminatedRegExpException
  • JSMin_UnterminatedStringException
  • LogicException
  • OAuthExcept
  • phpmailerException

Functions

  • __autoload
  • _escape_xref
  • _recaptcha_aes_encrypt
  • _recaptcha_aes_pad
  • _recaptcha_http_post
  • _recaptcha_mailhide_email_parts
  • _recaptcha_mailhide_urlbase64
  • _recaptcha_qsencode
  • accessAllAlbums
  • add_context
  • addalbumsToDatabase
  • addCategoriesToDatabase
  • addGeoCoord
  • addItem
  • addPagesToDatabase
  • addPluginScript
  • addPluginType
  • addSubalbumMenus
  • admin_album_list
  • admin_securityChecks
  • admin_showupdate
  • adminPageNav
  • adminToolbox
  • albumNumber
  • applyMacros
  • Auth_OpenID_arrangeByType
  • Auth_OpenID_AX_checkAlias
  • Auth_OpenID_AX_toTypeURIs
  • Auth_OpenID_bestMatchingService
  • Auth_OpenID_checkFieldName
  • Auth_OpenID_checkSessionType
  • Auth_OpenID_checkTimestamp
  • Auth_OpenID_detectMathLibrary
  • Auth_OpenID_discover
  • Auth_OpenID_discoverURI
  • Auth_OpenID_discoverWithoutYadis
  • Auth_OpenID_discoverWithYadis
  • Auth_OpenID_discoverXRI
  • Auth_OpenID_extractReturnURL
  • Auth_OpenID_findOPLocalIdentifier
  • Auth_OpenID_getAllAssociationTypes
  • Auth_OpenID_getAllowedReturnURLs
  • Auth_OpenID_getAuthorityPattern
  • Auth_OpenID_getAvailableSessionTypes
  • Auth_OpenID_getDefaultAssociationOrder
  • Auth_OpenID_getDefaultGen
  • Auth_OpenID_getDefaultMod
  • Auth_OpenID_getDefaultNegotiator
  • Auth_OpenID_getEncodedPattern
  • Auth_OpenID_getEncryptedNegotiator
  • Auth_OpenID_getEscapeRE
  • Auth_OpenID_getMathLib
  • Auth_OpenID_getOnlyEncryptedOrder
  • Auth_OpenID_getOpenIDConsumerTypeURIs
  • Auth_OpenID_getOpenIDTypeName
  • Auth_OpenID_getOpenIDTypeURIs
  • Auth_OpenID_getOPOrUserServices
  • Auth_OpenID_getSecretSize
  • Auth_OpenID_getSessionTypes
  • Auth_OpenID_getSupportedAssociationTypes
  • Auth_OpenID_getUnreserved
  • Auth_OpenID_getURIPattern
  • Auth_OpenID_getURLIllegalCharRE
  • Auth_OpenID_HMACSHA1
  • Auth_OpenID_HMACSHA256
  • Auth_OpenID_include_init
  • Auth_OpenID_isError
  • Auth_OpenID_isOpenID1
  • Auth_OpenID_legacy_discover
  • Auth_OpenID_makeOpenIDEndpoints
  • Auth_OpenID_math_extensions
  • Auth_OpenID_mkNonce
  • Auth_OpenID_noMathSupport
  • Auth_OpenID_pct_encoded_replace
  • Auth_OpenID_pct_encoded_replace_unreserved
  • Auth_OpenID_registerNamespaceAlias
  • Auth_OpenID_remove_dot_segments
  • Auth_OpenID_removeNamespaceAlias
  • Auth_OpenID_returnToMatches
  • Auth_OpenID_setNoMathSupport
  • Auth_OpenID_SHA1
  • Auth_OpenID_SHA256
  • Auth_OpenID_splitNonce
  • Auth_OpenID_supportsSReg
  • Auth_OpenID_urinorm
  • Auth_OpenID_verifyReturnTo
  • Auth_Yadis_array_scramble
  • Auth_Yadis_escapeForIRI
  • Auth_Yadis_getCanonicalID
  • Auth_Yadis_getDefaultProxy
  • Auth_Yadis_getEscapeRE
  • Auth_Yadis_getIPrivateChars
  • Auth_Yadis_getNSMap
  • Auth_Yadis_getServiceEndpoints
  • Auth_Yadis_getSupportedExtensions
  • Auth_Yadis_getUCSChars
  • Auth_Yadis_getXMLParser
  • Auth_Yadis_getXRDExpiration
  • Auth_Yadis_getXrefRE
  • Auth_Yadis_getXRIAuthorities
  • Auth_Yadis_identifierScheme
  • Auth_Yadis_iriToURI
  • Auth_Yadis_pct_escape_unicode
  • Auth_Yadis_providerIsAuthoritative
  • Auth_Yadis_rootAuthority
  • Auth_Yadis_setDefaultParser
  • Auth_Yadis_startswith
  • Auth_Yadis_toIRINormal
  • Auth_Yadis_toURINormal
  • Auth_Yadis_XRI
  • Auth_Yadis_XRIAppendArgs
  • authorSelector
  • build_query
  • build_url
  • bulkActionRedirect
  • bulkTags
  • byteConvert
  • cacheImage
  • checkAccess
  • checkAlbumimagesort
  • checkAlbumParentid
  • checkAlbumPassword
  • checkChosenItemStatus
  • checkChosenMenuset
  • checked
  • checkFolder
  • checkForEmptyTitle
  • checkForGuest
  • checkForPage
  • checkForPassword
  • checkForUpdate
  • checkHitcounterDisplay
  • checkIfChecked
  • checkIfLockedNews
  • checkIfLockedPage
  • checkIfNew
  • checkInstall
  • checkLayoutUseForImages
  • checkNewsAccess
  • checkNewsCategoryPassword
  • checkObjectsThumb
  • checkPagePassword
  • checkPageValidity
  • checkParentLayouts
  • checkPublishDates
  • checkRequiredField
  • checkSelectedAlbum
  • checkSignature
  • cleanAlbum
  • cleanHTML
  • clearSitemapCache
  • clonedFrom
  • codeblocktabsJS
  • comment_form_addComment
  • comment_form_handle_comment
  • comment_form_PaginationJS
  • comment_form_postcomment
  • comment_form_print10Most
  • comment_form_visualEditor
  • commentFormUseCaptcha
  • commentReply
  • commentsAllowed
  • consolidatedEditMessages
  • copyLayoutSelection
  • copyThemeDirectory
  • countArticles
  • countCombiNews
  • createMenuIfNotExists
  • createRelatedItemsResultArray
  • cron_starter
  • currentRelativeURL
  • customOptions
  • dateDiff
  • datepickerJS
  • dateTimeConvert
  • db_affected_rows
  • db_close
  • db_collation
  • db_connect
  • db_count
  • db_create
  • db_create_table
  • db_error
  • db_fetch_assoc
  • db_fetch_row
  • db_free_result
  • db_getSQLmode
  • db_insert_id
  • db_LIKE_escape
  • db_list_fields
  • db_name
  • db_num_rows
  • db_permissions
  • db_quote
  • db_setSQLmode
  • db_show
  • db_software
  • db_table_update
  • db_truncate_table
  • debug404
  • debugLog
  • debugLogBacktrace
  • debugLogVar
  • defaultCodeblocks_codebox
  • deleteArticle
  • deleteCategory
  • deleteItem
  • deleteLayoutSelection
  • deletePage
  • deleteThemeDirectory
  • detect_fetcher
  • detect_math
  • detect_query_corruption
  • detect_random
  • detect_stores
  • detect_xml
  • dircopy
  • displayError
  • doIncludes
  • elFinder_admin_tabs
  • elFinder_tinymce
  • enableExtension
  • escape
  • executeRSS
  • exitZP
  • exposeZenPhotoInformations
  • extensionEnabled
  • fetchComments
  • filesystemToInternal
  • filter_extractReturnURL
  • filter_MatchesAnyOpenIDConsumerType
  • filter_MatchesAnyOpenIDType
  • filterImageQuery
  • fix_path_redirect
  • formatList
  • fullText
  • galleryAlbumsPerPage
  • genAlbumList
  • generateCaptcha
  • generateLanguageList
  • generateListFromArray
  • generateListFromFiles
  • generateRadiobuttonsFromArray
  • generateSitemapCacheFile
  • generateSitemapIndexCacheFile
  • generateUnorderedListFromArray
  • get_AnyFile_suffixes
  • get_context
  • get_filterScript
  • get_instance
  • get_language_string
  • getAdminThumb
  • getAlbumArray
  • getAlbumBreadcrumb
  • getAlbumBreadcrumbAdmin
  • getAlbumCustomData
  • getAlbumData
  • getAlbumDate
  • getAlbumDesc
  • getAlbumFolder
  • getAlbumGeodata
  • getAlbumId
  • getAlbumInherited
  • getAlbumLinkURL
  • getAlbumLocation
  • getAlbumPage
  • getAlbumPlace
  • getAlbumStatistic
  • getAlbumThumb
  • getAlbumTitle
  • getAlbumURL
  • getAllAccessibleAlbums
  • getAllAlbums
  • getAllArticleDates
  • getAllCategories
  • getAllDates
  • getAllowedTags
  • getAllSubAlbumIDs
  • getAllSubalbums
  • getAllTagsCount
  • getAllTagsFromAlbum
  • getAllTagsFromAlbum_multi_unique
  • getAllTagsFromZenpage
  • getAllTagsUnique
  • getAllTranslations
  • getAnnotatedAlbumTitle
  • getAnnotatedImageTitle
  • getArticles
  • getAuthor
  • getBare
  • getBareAlbumDesc
  • getBareAlbumTitle
  • getBareGalleryDesc
  • getBareGalleryTitle
  • getBareImageDesc
  • getBareImageTitle
  • getBareNewsAlbumTitle
  • getBareNewsTitle
  • getBarePageTitle
  • getCategory
  • getCategoryID
  • getCategoryLink
  • getCategoryParentID
  • getCategorySortOrder
  • getCategoryTitle
  • getCheckboxState
  • getCodeblock
  • getCombiNews
  • getCommentAddress
  • getCommentAuthorEmail
  • getCommentAuthorLink
  • getCommentAuthorName
  • getCommentAuthorSite
  • getCommentBody
  • getCommentCount
  • getCommentDate
  • getCommentDateTime
  • getCommentErrors
  • getCommentsAllowed
  • getCommentStored
  • getCommentTime
  • getConsumer
  • getContentShorten
  • getCurrentMenuItem
  • getCurrentNewsArchive
  • getCurrentNewsCategory
  • getCurrentNewsCategoryID
  • getCurrentNewsCategoryParentID
  • getCurrentNewsPage
  • getCurrentPage
  • getCurrentTheme
  • getCustomAlbumThumb
  • getCustomAlbumThumbMaxSpace
  • getCustomImageURL
  • getCustomPageURL
  • getCustomSizedImageMaxSpace
  • getCustomSizedImageThumbMaxSpace
  • getDefaultHeight
  • getDefaultSizedImage
  • getDefaultWidth
  • getDownloadLink
  • getdownloadList
  • getDownloadURL
  • getE
  • getEnabledPlugins
  • getExpiryDatePost
  • getFavoritesURL
  • getField
  • getFirstImageURL
  • getFullHeight
  • getFullImageURL
  • getFullNewsImage
  • getFullWidth
  • getGalleryDesc
  • getGalleryIndexURL
  • getGalleryTitle
  • getGeoCoord
  • getHeadTitle
  • getHitcounter
  • getImageArgs
  • getImageCacheFilename
  • getImageCachePostfix
  • getImageCity
  • getImageCountry
  • getImageCustomData
  • getImageData
  • getImageDate
  • getImageDesc
  • getImageEXIFData
  • getImageGeodata
  • getImageID
  • getImageLinkURL
  • getImageLocation
  • getImageMetaData
  • getImageParameters
  • getImageProcessorURI
  • getImageProcessorURIFromCacheName
  • getImageRotation
  • getImageSortOrder
  • getImageState
  • getImageStatistic
  • getImageThumb
  • getImageTitle
  • getImageURI
  • getImageURL
  • getItem
  • getItemByID
  • getItemTitleAndURL
  • getjPlayerSkinCSS
  • getjPlayerSkins
  • getLanguageArray
  • getLanguageFlag
  • getLastImageURL
  • getLatestComments
  • getLatestNews
  • getLatestZenpageComments
  • getLayout
  • getLayoutSelector
  • getLink
  • getLinkHTML
  • getLogTabs
  • getMacros
  • getMainSiteName
  • getMainSiteURL
  • getManagedAlbumList
  • getMaxSpaceContainer
  • getMenuFromLink
  • getMenuItemChilds
  • getMenuItems
  • getMenumanagerPredicessor
  • getMenumanagerSuccessor
  • getMenuSetSelector
  • getMenuVisibility
  • getMimeString
  • getNestedAlbumList
  • getNewsAdminOption
  • getNewsAdminOptionPath
  • getNewsAlbumName
  • getNewsAlbumTitle
  • getNewsAlbumURL
  • getNewsArchivePath
  • getNewsArchiveURL
  • getNewsAuthor
  • getNewsCategories
  • getNewsCategoryCustomData
  • getNewsCategoryDesc
  • getNewsCategoryPath
  • getNewsCategoryURL
  • getNewsContent
  • getNewsContentShorten
  • getNewsCustomData
  • getNewsDate
  • getNewsExtraContent
  • getNewsID
  • getNewsImageTags
  • getNewsIndexURL
  • getNewsLink
  • getNewsPagesStatistic
  • getNewsPathNav
  • getNewsReadMore
  • getNewsTitle
  • getNewsTitleLink
  • getNewsTitlePath
  • getNewsType
  • getNewsURL
  • getNewsVideoContent
  • getNextAlbum
  • getNextAlbumURL
  • getNextImageThumb
  • getNextImageURL
  • getNextNewsPageURL
  • getNextNewsURL
  • getNextPageURL
  • getNextPrevNews
  • getNotViewableAlbums
  • getNotViewableImages
  • getNumAlbums
  • getNumAllSubalbums
  • getNumImages
  • getNumNews
  • getNumPages
  • getNumSubalbums
  • getOpenIDURL
  • getOption
  • getOptionFromDB
  • getOptionList
  • getPageAuthor
  • getPageContent
  • getPageCustomData
  • getPageDate
  • getPageExtraContent
  • getPageID
  • getPageLastChangeDate
  • getPageLinkPath
  • getPageLinkURL
  • getPageNavList
  • getPageNumURL
  • getPageParentID
  • getPageRedirect
  • getPages
  • getPageSelector
  • getPageSortorder
  • getPageTitle
  • getPageTitleLink
  • getPageURL
  • getParentAlbums
  • getParentAlbumsAdmin
  • getParentBreadcrumb
  • getParentItems
  • getParentMenuItems
  • getParentNewsCategories
  • getParentPages
  • getPasswordProtectImage
  • getPHPFiles
  • getPlugin
  • getPluginFiles
  • getPluginTabs
  • getPrevAlbum
  • getPrevAlbumURL
  • getPrevImageThumb
  • getPrevImageURL
  • getPrevNewsPageURL
  • getPrevNewsURL
  • getPrevPageURL
  • getProtectedImageURL
  • getRandomImages
  • getRandomImagesAlbum
  • getRating
  • getRelatedItems
  • getRequestURI
  • getReturnTo
  • getRSSHeaderLink
  • getRSSLink
  • getScheme
  • getSearchDate
  • getSearchURL
  • getSearchWords
  • getSelectedLayout
  • getSerializedArray
  • getSetClause
  • getSiteHomeURL
  • getSitemapAlbumList
  • getSitemapAlbums
  • getSitemapGoogleImageVideoExtras
  • getSitemapGoogleLoopIndex
  • getSitemapImages
  • getSitemapIndexLinks
  • getSitemapZenpageNewsArticles
  • getSitemapZenpageNewsCategories
  • getSitemapZenpageNewsIndex
  • getSitemapZenpagePages
  • getSizeCustomImage
  • getSizeDefaultImage
  • getSizeDefaultThumb
  • getSizedImageURL
  • getSizeFullImage
  • getStore
  • getSubCategories
  • getSubtabs
  • getSuffix
  • getTagCountByAccess
  • getTagOrder
  • getTags
  • gettext_pl
  • gettext_th
  • getTheme
  • getThemeFiles
  • getThemeOption
  • getTimezones
  • getTinyMCE4ConfigFiles
  • getTitle
  • getTotalArticles
  • getTotalImagesIn
  • getTotalNewsPages
  • getTotalPages
  • getTrustRoot
  • getUnprotectedImageURL
  • getUrAlbum
  • getURL
  • getUserIP
  • getUserLocale
  • getVersion
  • getViewerImageSize
  • getWatermarkParam
  • getWatermarkPath
  • getWatermarks
  • getWhereClause
  • getXSRFToken
  • getZenpageHitcounter
  • getZenpageRSSHeaderLink
  • getZenpageRSSLink
  • getZenpageStatistic
  • googleVerifyHead
  • handleSearchParms
  • hasDynamicAlbumSuffix
  • hasNextImage
  • hasNextPage
  • hasPrevImage
  • hasPrevPage
  • hitcounter
  • html_decode
  • html_encode
  • html_encodeTagged
  • httpsRedirect
  • httpUploadHandler
  • httpUploadHandler_admin_tabs
  • i18nSetLocale
  • imageBlurGD
  • imageDebug
  • imageError
  • imageNumber
  • imgSrcURI
  • in_context
  • inNewsCategory
  • inProtectedNewsCategory
  • installSignature
  • instrument
  • inSubNewsCategoryOf
  • internalToFilesystem
  • inventMenuItem
  • iptc_make_tag
  • is_AdminEditPage
  • is_connected
  • is_GalleryNewsType
  • is_News
  • is_NewsArchive
  • is_NewsArticle
  • is_NewsCategory
  • is_NewsPage
  • is_NewsType
  • is_Pages
  • is_valid_email_zp
  • is_valid_image
  • is_valid_other_type
  • is_zip
  • isAlbumClass
  • isAlbumPage
  • isArchive
  • isHandledAlbum
  • isImageClass
  • isImagePage
  • isImagePhoto
  • isImageVideo
  • isLandscape
  • isMyAlbum
  • isMyNews
  • isMyPage
  • isolate
  • isProtectedAlbum
  • isProtectedNewsCategory
  • isProtectedPage
  • isSubNewsCategoryOf
  • isValidURL
  • jQueryUpload_head
  • jQueryUpload_headers
  • jQueryUploadHandler
  • jQueryUploadHandler_admin_tabs
  • js_encode
  • json_decode
  • json_encode
  • kses
  • kses_array_lc
  • kses_attr
  • kses_bad_protocol
  • kses_bad_protocol_once
  • kses_bad_protocol_once2
  • kses_check_attr_val
  • kses_decode_entities
  • kses_hair
  • kses_hook
  • kses_html_error
  • kses_js_entities
  • kses_no_null
  • kses_normalize_entities
  • kses_normalize_entities2
  • kses_split
  • kses_split2
  • kses_stripslashes
  • kses_version
  • ksesProcess
  • layoutSelector
  • layoutSelector_album
  • listDBUses
  • listDirectoryFiles
  • listUses
  • load_zenpage_news
  • load_zenpage_pages
  • loadLocalOptions
  • log_message
  • lookupSortKey
  • macro_admin_tabs
  • macroList_show
  • makeAlbumCurrent
  • makeImageCurrent
  • makeSpecialImageName
  • markRelease_button
  • mb_strlen
  • mb_strpos
  • mb_strrpos
  • mb_strtolower
  • mb_strtoupper
  • mb_substr
  • mb_substr_count
  • menu_admin_toolbox_global
  • menu_tabs
  • minDiff
  • mkdir_recursive
  • my_truncate_string
  • myts_date
  • newAlbum
  • newImage
  • next_album
  • next_comment
  • next_image
  • next_news
  • next_page
  • ngettext_pl
  • ngettext_th
  • normalizeColumns
  • omsAdditions
  • openedForComments
  • parse_query
  • parse_size
  • parseAllowedTags
  • parseHttpAcceptLanguage
  • passAlbums
  • passImages
  • pathurlencode
  • PclZipUtilCopyBlock
  • PclZipUtilOptionText
  • PclZipUtilPathInclusion
  • PclZipUtilPathReduction
  • PclZipUtilRename
  • PclZipUtilTranslateWinPath
  • PHPMailerAutoload
  • populateManagedObjectsList
  • postAlbumSort
  • postIndexDecode
  • postIndexEncode
  • prefix
  • prepareAlbumPage
  • prepareCustomPage
  • prepareImagePage
  • prepareIndexPage
  • print404status
  • print_language_string_list
  • printAddToFavorites
  • printAdminFooter
  • printAdminHeader
  • printAdminRightsTable
  • printAdminToolbox
  • printAlbumBreadcrumb
  • printAlbumButtons
  • printAlbumCustomData
  • printAlbumData
  • printAlbumDate
  • printAlbumDesc
  • printAlbumEditForm
  • printAlbumEditRow
  • printAlbumLegend
  • printAlbumLink
  • printAlbumLocation
  • printAlbumMap
  • printAlbumMenu
  • printAlbumMenuJump
  • printAlbumMenuList
  • printAlbumMenuListAlbum
  • printAlbumPlace
  • printAlbumRating
  • printAlbumsSelector
  • printAlbumStatistic
  • printAlbumStatisticItem
  • printAlbumThumbImage
  • printAlbumTitle
  • printAlbumURL
  • printAlbumZip
  • printAllDates
  • printAllNewsCategories
  • printAllTags
  • printAllTagsAs
  • printAllTagsFromAlbum
  • printAllTagsFromZenpage
  • printAnnotatedAlbumTitle
  • printAnnotatedImageTitle
  • printArticleCategories
  • printArticleDatesDropdown
  • printArticlesPerPageDropdown
  • printBareAlbumDesc
  • printBareAlbumTitle
  • printBareGalleryDesc
  • printBareGalleryTitle
  • printBareImageDesc
  • printBareImageTitle
  • printBareNewsTitle
  • printBarePageTitle
  • printBulkActions
  • printCaptcha
  • printCategoriesStatistic
  • printCategoryCheckboxListEntry
  • printCategoryDropdown
  • printCategoryListSortableTable
  • printCategorySelection
  • printCodeblock
  • printCodeblockEdit
  • printCommentAuthorLink
  • printCommentErrors
  • printCommentForm
  • printContactForm
  • printCurrentNewsArchive
  • printCurrentNewsCategory
  • printCustomAlbumThumbImage
  • printCustomAlbumThumbMaxSpace
  • printCustomMenu
  • printCustomPageSelector
  • printCustomPageURL
  • printCustomSizedImage
  • printCustomSizedImageMaxHeight
  • printCustomSizedImageMaxSpace
  • printCustomSizedImageThumbMaxSpace
  • printDefaultSizedImage
  • printDownloadAlbumZipURL
  • printDownloadLink
  • printDownloadLinkAlbumZip
  • printdownloadList
  • printDownloadURL
  • printEditable
  • printEditCommentLink
  • printEditDropdown
  • printExpired
  • printFavoritesLink
  • printFavoritesURL
  • printField
  • printGalleryDesc
  • printGalleryIndexURL
  • printGalleryTitle
  • printGoogleMap
  • printHeadTitle
  • printHomeLink
  • printImageCustomData
  • printImageData
  • printImageDate
  • printImageDesc
  • printImageDiv
  • printImageEXIFData
  • printImageID
  • printImageLink
  • printImageMap
  • printImageMetadata
  • printImageRating
  • printImageSortOrder
  • printImageStatistic
  • printImageThumb
  • printImageTitle
  • printImageURL
  • printItemEditLink
  • printItemsList
  • printItemsListTable
  • printItemStatusDropdown
  • printjCarouselThumbNav
  • printjPlayerPlaylist
  • printLanguageSelector
  • printLatestAlbums
  • printLatestComments
  • printLatestImages
  • printLatestImagesByDate
  • printLatestImagesByMtime
  • printLatestNews
  • printLatestUpdatedAlbums
  • printLatestZenpageComments
  • printLink
  • printLinkHTML
  • printLogoAndLinks
  • printManagedObjects
  • printMenuemanagerPageList
  • printMenuemanagerPageListWithNav
  • printMenumanagerBreadcrumb
  • printMenumanagerNextLink
  • printMenumanagerPrevLink
  • printMostPopularItems
  • printMostRatedAlbums
  • printMostRatedImages
  • printMostRatedItems
  • printNestedAlbumsList
  • printNestedItemsList
  • printNestedMenu
  • printNews
  • printNewsArchive
  • printNewsAuthor
  • printNewsCategories
  • printNewsCategoryCustomData
  • printNewsCategoryDesc
  • printNewsCategoryURL
  • printNewsContent
  • printNewsCustomData
  • printNewsDate
  • printNewsExtraContent
  • printNewsImageTags
  • printNewsIndexURL
  • printNewsLink
  • printNewsPageList
  • printNewsPageListWithNav
  • printNewsReadMoreLink
  • printNewsStatistic
  • printNewsTitle
  • printNewsTitleLink
  • printNewsURL
  • printNextNewsLink
  • printNextNewsPageLink
  • printNextPageLink
  • printNextPageURL
  • printPageArticleTags
  • printPageAuthor
  • printPageContent
  • printPageCustomData
  • printPageDate
  • printPagedThumbsNav
  • printPageExtraContent
  • printPageID
  • printPageLastChangeDate
  • printPageLinkURL
  • printPageList
  • printPageListWithNav
  • printPageMenu
  • printPageNav
  • printPageSelector
  • printPagesListTable
  • printPagesStatistic
  • printPageTitle
  • printPageTitleLink
  • printPageURL
  • printParentBreadcrumb
  • printParentPagesBreadcrumb
  • printPasswordForm
  • printPopularAlbums
  • printPopularImages
  • printPreloadScript
  • printPrevNewsLink
  • printPrevNewsPageLink
  • printPrevPageLink
  • printPrevPageURL
  • printPublished
  • printPublishIconLink
  • printRandomImages
  • printRating
  • printRegisterURL
  • printRegistrationForm
  • printRelatedItems
  • printRSSHeaderLink
  • printRSSLink
  • printSearchBreadcrumb
  • printSearchForm
  • printSiteHomeURL
  • printSizedImageLink
  • printSizedImageURL
  • printSlideShow
  • printSlideShowJS
  • printSlideShowLink
  • printSortableHead
  • printSortOrderDropdown
  • printSubPagesExcerpts
  • printSubtabs
  • printTabs
  • printTags
  • printThumbNav
  • printTopRatedAlbums
  • printTopRatedImages
  • printTopRatedItems
  • printUnpublishedDropdown
  • printUserLogin_out
  • printUserSizeImage
  • printUserSizeSelector
  • printVersion
  • printZenJavascripts
  • printZenpageIconLegend
  • printZenpageItemsBreadcrumb
  • printZenpageNewsCategorySelector
  • printZenpagePagesSelector
  • printZenpageRSSHeaderLink
  • printZenpageRSSLink
  • printZenpageStatistic
  • printZenphotoLink
  • process_language_string_save
  • processAlbumBulkActions
  • processAlbumEdit
  • processCodeblockSave
  • processCommentBulkActions
  • processCredentials
  • processCustomOptionSave
  • processEditSelection
  • processExpired
  • processImageBulkActions
  • processImageEdit
  • processManagedObjects
  • processMenuBulkActions
  • processOrder
  • processRights
  • processTags
  • processZenpageBulkActions
  • propSizes
  • publishItem
  • purgeOption
  • query
  • query_full_array
  • query_single_row
  • rc4
  • read_exif_data_protected
  • readTags
  • recaptcha_check_answer
  • recaptcha_get_html
  • recaptcha_get_signup_url
  • recaptcha_mailhide_html
  • recaptcha_mailhide_url
  • reconfigureAction
  • reconfigureCS
  • reconfigurePage
  • recordMissing
  • rem_context
  • removeParentAlbumNames
  • resetCurrentAlbum
  • restore_context
  • reveal
  • rewrite_get_album_image
  • rewrite_path
  • rewrite_path_zenpage
  • RSS_Channel
  • RSS_Retrieve
  • RSS_Tags
  • rulesList
  • run
  • safe_fnmatch
  • safe_glob
  • sanitize
  • sanitize_numeric
  • sanitize_path
  • sanitize_script
  • sanitize_string
  • sanitizeRedirect
  • save_context
  • saveLayoutSelection
  • saveZenphotoLayoutSelection
  • search_quote
  • secureServer
  • seo_cleanup_button
  • seoFriendly
  • seoFriendlyJS
  • set_context
  • setAlbumCustomData
  • setAlbumSubtabs
  • setImageCustomData
  • setMainDomain
  • setOption
  • setOptionDefault
  • setPluginDomain
  • setThemeColumns
  • setThemeDomain
  • setThemeOption
  • setThemeOptionDefault
  • setupAllowedMaps
  • setupCurrentLocale
  • setupDomain
  • setupTheme
  • shortenContent
  • showOrNotShowField
  • shuffle_assoc
  • signatureChange
  • site_upgrade_button
  • site_upgrade_status
  • sitemap_echonl
  • sitemap_getChangefreq
  • sitemap_getDateformat
  • sitemap_getDBLimit
  • sitemap_getISO8601Date
  • skipScheduledPublishing
  • sortByKey
  • sortByMultilingual
  • sortMultiArray
  • standardScripts
  • standardThemeOptions
  • stickyNews
  • storeConfig
  • storeTags
  • stripSuffix
  • submenuOf
  • switchLog
  • tagSelector
  • tagSuggestJS
  • tagSuggestJS_admin
  • tagSuggestJS_frontend
  • themeIsEditable
  • themeSetup
  • timezoneDiff
  • tinymce4ConfigJS
  • truncate_string
  • unpublishedZenphotoItemCheck
  • unpublishSubalbums
  • unQuote
  • unzip
  • updateArticle
  • updateCacheName
  • updateCategory
  • updateConfigItem
  • updateItemSortorder
  • updateItemsSortorder
  • updateMenuItem
  • updatePage
  • upload_extra
  • upload_form
  • upload_head
  • user_mailing_list_button
  • validateLocale
  • wordpress_import_button
  • wp_prefix
  • wp_query_full_array
  • wpimport_TryAgainError
  • XSRFdefender
  • XSRFToken
  • zenJavascript
  • zenpageAlbumImage
  • zenpageBulkActionMessage
  • zenpageHitcounter
  • zenpageJSCSS
  • zenpageOpenedForComments
  • zenpagePublish
  • zenphoto_PHPMailer
  • zenphoto_sendmail
  • zenPhotoTheme
  • zp_apply_filter
  • zp_clearCookie
  • zp_colorAllocate
  • zp_cookieEncode
  • zp_copyCanvas
  • zp_createImage
  • zp_drawRectangle
  • zp_error
  • zp_filter_slot
  • zp_filter_unique_id
  • zp_getCookie
  • zp_getFonts
  • zp_graphicsLibInfo
  • zp_handle_password
  • zp_handle_password_single
  • zp_has_filter
  • zp_image_types
  • zp_imageCanRotate
  • zp_imageColorTransparent
  • zp_imageDims
  • zp_imageFill
  • zp_imageFontHeight
  • zp_imageFontWidth
  • zp_imageFromString
  • zp_imageGet
  • zp_imageGray
  • zp_imageHeight
  • zp_imageIPTC
  • zp_imageKill
  • zp_imageLoadFont
  • zp_imageMerge
  • zp_imageOutput
  • zp_imageResizeAlpha
  • zp_imageUnsharpMask
  • zp_imageWidth
  • zp_load_album
  • zp_load_gallery
  • zp_load_image
  • zp_load_page
  • zp_load_request
  • zp_load_search
  • zp_loggedin
  • zp_mail
  • zp_register_filter
  • zp_remove_filter
  • zp_resampleImage
  • zp_rotateImage
  • zp_session_start
  • zp_setCookie
  • zp_writeString
  • zpErrorHandler
  • zpFormattedDate
  • zpRewriteURL
  • Overview
  • Package
  • Class
  • Tree
  • Deprecated
   1: <?php
   2: 
   3: /**
   4:  * This module documents the main interface with the OpenID consumer
   5:  * library.  The only part of the library which has to be used and
   6:  * isn't documented in full here is the store required to create an
   7:  * Auth_OpenID_Consumer instance.  More on the abstract store type and
   8:  * concrete implementations of it that are provided in the
   9:  * documentation for the Auth_OpenID_Consumer constructor.
  10:  *
  11:  * OVERVIEW
  12:  *
  13:  * The OpenID identity verification process most commonly uses the
  14:  * following steps, as visible to the user of this library:
  15:  *
  16:  *   1. The user enters their OpenID into a field on the consumer's
  17:  *      site, and hits a login button.
  18:  *   2. The consumer site discovers the user's OpenID server using the
  19:  *      YADIS protocol.
  20:  *   3. The consumer site sends the browser a redirect to the identity
  21:  *      server.  This is the authentication request as described in
  22:  *      the OpenID specification.
  23:  *   4. The identity server's site sends the browser a redirect back
  24:  *      to the consumer site.  This redirect contains the server's
  25:  *      response to the authentication request.
  26:  *
  27:  * The most important part of the flow to note is the consumer's site
  28:  * must handle two separate HTTP requests in order to perform the full
  29:  * identity check.
  30:  *
  31:  * LIBRARY DESIGN
  32:  *
  33:  * This consumer library is designed with that flow in mind.  The goal
  34:  * is to make it as easy as possible to perform the above steps
  35:  * securely.
  36:  *
  37:  * At a high level, there are two important parts in the consumer
  38:  * library.  The first important part is this module, which contains
  39:  * the interface to actually use this library.  The second is the
  40:  * Auth_OpenID_Interface class, which describes the interface to use
  41:  * if you need to create a custom method for storing the state this
  42:  * library needs to maintain between requests.
  43:  *
  44:  * In general, the second part is less important for users of the
  45:  * library to know about, as several implementations are provided
  46:  * which cover a wide variety of situations in which consumers may use
  47:  * the library.
  48:  *
  49:  * This module contains a class, Auth_OpenID_Consumer, with methods
  50:  * corresponding to the actions necessary in each of steps 2, 3, and 4
  51:  * described in the overview.  Use of this library should be as easy
  52:  * as creating an Auth_OpenID_Consumer instance and calling the
  53:  * methods appropriate for the action the site wants to take.
  54:  *
  55:  * STORES AND DUMB MODE
  56:  *
  57:  * OpenID is a protocol that works best when the consumer site is able
  58:  * to store some state.  This is the normal mode of operation for the
  59:  * protocol, and is sometimes referred to as smart mode.  There is
  60:  * also a fallback mode, known as dumb mode, which is available when
  61:  * the consumer site is not able to store state.  This mode should be
  62:  * avoided when possible, as it leaves the implementation more
  63:  * vulnerable to replay attacks.
  64:  *
  65:  * The mode the library works in for normal operation is determined by
  66:  * the store that it is given.  The store is an abstraction that
  67:  * handles the data that the consumer needs to manage between http
  68:  * requests in order to operate efficiently and securely.
  69:  *
  70:  * Several store implementation are provided, and the interface is
  71:  * fully documented so that custom stores can be used as well.  See
  72:  * the documentation for the Auth_OpenID_Consumer class for more
  73:  * information on the interface for stores.  The implementations that
  74:  * are provided allow the consumer site to store the necessary data in
  75:  * several different ways, including several SQL databases and normal
  76:  * files on disk.
  77:  *
  78:  * There is an additional concrete store provided that puts the system
  79:  * in dumb mode.  This is not recommended, as it removes the library's
  80:  * ability to stop replay attacks reliably.  It still uses time-based
  81:  * checking to make replay attacks only possible within a small
  82:  * window, but they remain possible within that window.  This store
  83:  * should only be used if the consumer site has no way to retain data
  84:  * between requests at all.
  85:  *
  86:  * IMMEDIATE MODE
  87:  *
  88:  * In the flow described above, the user may need to confirm to the
  89:  * lidentity server that it's ok to authorize his or her identity.
  90:  * The server may draw pages asking for information from the user
  91:  * before it redirects the browser back to the consumer's site.  This
  92:  * is generally transparent to the consumer site, so it is typically
  93:  * ignored as an implementation detail.
  94:  *
  95:  * There can be times, however, where the consumer site wants to get a
  96:  * response immediately.  When this is the case, the consumer can put
  97:  * the library in immediate mode.  In immediate mode, there is an
  98:  * extra response possible from the server, which is essentially the
  99:  * server reporting that it doesn't have enough information to answer
 100:  * the question yet.
 101:  *
 102:  * USING THIS LIBRARY
 103:  *
 104:  * Integrating this library into an application is usually a
 105:  * relatively straightforward process.  The process should basically
 106:  * follow this plan:
 107:  *
 108:  * Add an OpenID login field somewhere on your site.  When an OpenID
 109:  * is entered in that field and the form is submitted, it should make
 110:  * a request to the your site which includes that OpenID URL.
 111:  *
 112:  * First, the application should instantiate the Auth_OpenID_Consumer
 113:  * class using the store of choice (Auth_OpenID_FileStore or one of
 114:  * the SQL-based stores).  If the application has a custom
 115:  * session-management implementation, an object implementing the
 116:  * {@link Auth_Yadis_PHPSession} interface should be passed as the
 117:  * second parameter.  Otherwise, the default uses $_SESSION.
 118:  *
 119:  * Next, the application should call the Auth_OpenID_Consumer object's
 120:  * 'begin' method.  This method takes the OpenID URL.  The 'begin'
 121:  * method returns an Auth_OpenID_AuthRequest object.
 122:  *
 123:  * Next, the application should call the 'redirectURL' method of the
 124:  * Auth_OpenID_AuthRequest object.  The 'return_to' URL parameter is
 125:  * the URL that the OpenID server will send the user back to after
 126:  * attempting to verify his or her identity.  The 'trust_root' is the
 127:  * URL (or URL pattern) that identifies your web site to the user when
 128:  * he or she is authorizing it.  Send a redirect to the resulting URL
 129:  * to the user's browser.
 130:  *
 131:  * That's the first half of the authentication process.  The second
 132:  * half of the process is done after the user's ID server sends the
 133:  * user's browser a redirect back to your site to complete their
 134:  * login.
 135:  *
 136:  * When that happens, the user will contact your site at the URL given
 137:  * as the 'return_to' URL to the Auth_OpenID_AuthRequest::redirectURL
 138:  * call made above.  The request will have several query parameters
 139:  * added to the URL by the identity server as the information
 140:  * necessary to finish the request.
 141:  *
 142:  * Lastly, instantiate an Auth_OpenID_Consumer instance as above and
 143:  * call its 'complete' method, passing in all the received query
 144:  * arguments.
 145:  *
 146:  * There are multiple possible return types possible from that
 147:  * method. These indicate the whether or not the login was successful,
 148:  * and include any additional information appropriate for their type.
 149:  *
 150:  * PHP versions 4 and 5
 151:  *
 152:  * LICENSE: See the COPYING file included in this distribution.
 153:  *
 154:  * @package OpenID
 155:  * @author JanRain, Inc. <openid@janrain.com>
 156:  * @copyright 2005-2008 Janrain, Inc.
 157:  * @license http://www.apache.org/licenses/LICENSE-2.0 Apache
 158:  */
 159: 
 160: /**
 161:  * Require utility classes and functions for the consumer.
 162:  */
 163: require_once "Auth/OpenID.php";
 164: require_once "Auth/OpenID/Message.php";
 165: require_once "Auth/OpenID/HMAC.php";
 166: require_once "Auth/OpenID/Association.php";
 167: require_once "Auth/OpenID/CryptUtil.php";
 168: require_once "Auth/OpenID/DiffieHellman.php";
 169: require_once "Auth/OpenID/KVForm.php";
 170: require_once "Auth/OpenID/Nonce.php";
 171: require_once "Auth/OpenID/Discover.php";
 172: require_once "Auth/OpenID/URINorm.php";
 173: require_once "Auth/Yadis/Manager.php";
 174: require_once "Auth/Yadis/XRI.php";
 175: 
 176: /**
 177:  * This is the status code returned when the complete method returns
 178:  * successfully.
 179:  */
 180: define('Auth_OpenID_SUCCESS', 'success');
 181: 
 182: /**
 183:  * Status to indicate cancellation of OpenID authentication.
 184:  */
 185: define('Auth_OpenID_CANCEL', 'cancel');
 186: 
 187: /**
 188:  * This is the status code completeAuth returns when the value it
 189:  * received indicated an invalid login.
 190:  */
 191: define('Auth_OpenID_FAILURE', 'failure');
 192: 
 193: /**
 194:  * This is the status code completeAuth returns when the
 195:  * {@link Auth_OpenID_Consumer} instance is in immediate mode, and the
 196:  * identity server sends back a URL to send the user to to complete his
 197:  * or her login.
 198:  */
 199: define('Auth_OpenID_SETUP_NEEDED', 'setup needed');
 200: 
 201: /**
 202:  * This is the status code beginAuth returns when the page fetched
 203:  * from the entered OpenID URL doesn't contain the necessary link tags
 204:  * to function as an identity page.
 205:  */
 206: define('Auth_OpenID_PARSE_ERROR', 'parse error');
 207: 
 208: /**
 209:  * An OpenID consumer implementation that performs discovery and does
 210:  * session management.  See the Consumer.php file documentation for
 211:  * more information.
 212:  *
 213:  * @package OpenID
 214:  */
 215: class Auth_OpenID_Consumer {
 216: 
 217:     /**
 218:      * @access private
 219:      */
 220:     var $discoverMethod = 'Auth_OpenID_discover';
 221: 
 222:     /**
 223:      * @access private
 224:      */
 225:     var $session_key_prefix = "_openid_consumer_";
 226: 
 227:     /**
 228:      * @access private
 229:      */
 230:     var $_token_suffix = "last_token";
 231: 
 232:     /**
 233:      * Initialize a Consumer instance.
 234:      *
 235:      * You should create a new instance of the Consumer object with
 236:      * every HTTP request that handles OpenID transactions.
 237:      *
 238:      * @param Auth_OpenID_OpenIDStore $store This must be an object
 239:      * that implements the interface in {@link
 240:      * Auth_OpenID_OpenIDStore}.  Several concrete implementations are
 241:      * provided, to cover most common use cases.  For stores backed by
 242:      * MySQL, PostgreSQL, or SQLite, see the {@link
 243:      * Auth_OpenID_SQLStore} class and its sublcasses.  For a
 244:      * filesystem-backed store, see the {@link Auth_OpenID_FileStore}
 245:      * module.  As a last resort, if it isn't possible for the server
 246:      * to store state at all, an instance of {@link
 247:      * Auth_OpenID_DumbStore} can be used.
 248:      *
 249:      * @param mixed $session An object which implements the interface
 250:      * of the {@link Auth_Yadis_PHPSession} class.  Particularly, this
 251:      * object is expected to have these methods: get($key), set($key),
 252:      * $value), and del($key).  This defaults to a session object
 253:      * which wraps PHP's native session machinery.  You should only
 254:      * need to pass something here if you have your own sessioning
 255:      * implementation.
 256:      *
 257:      * @param str $consumer_cls The name of the class to instantiate
 258:      * when creating the internal consumer object.  This is used for
 259:      * testing.
 260:      */
 261:     function Auth_OpenID_Consumer($store, $session = null,
 262:                                   $consumer_cls = null)
 263:     {
 264:         if ($session === null) {
 265:             $session = new Auth_Yadis_PHPSession();
 266:         }
 267: 
 268:         $this->session = $session;
 269: 
 270:         if ($consumer_cls !== null) {
 271:             $this->consumer = new $consumer_cls($store);
 272:         } else {
 273:             $this->consumer = new Auth_OpenID_GenericConsumer($store);
 274:         }
 275: 
 276:         $this->_token_key = $this->session_key_prefix . $this->_token_suffix;
 277:     }
 278: 
 279:     /**
 280:      * Used in testing to define the discovery mechanism.
 281:      *
 282:      * @access private
 283:      */
 284:     function getDiscoveryObject($session, $openid_url,
 285:                                 $session_key_prefix)
 286:     {
 287:         return new Auth_Yadis_Discovery($session, $openid_url,
 288:                                         $session_key_prefix);
 289:     }
 290: 
 291:     /**
 292:      * Start the OpenID authentication process. See steps 1-2 in the
 293:      * overview at the top of this file.
 294:      *
 295:      * @param string $user_url Identity URL given by the user. This
 296:      * method performs a textual transformation of the URL to try and
 297:      * make sure it is normalized. For example, a user_url of
 298:      * example.com will be normalized to http://example.com/
 299:      * normalizing and resolving any redirects the server might issue.
 300:      *
 301:      * @param bool $anonymous True if the OpenID request is to be sent
 302:      * to the server without any identifier information.  Use this
 303:      * when you want to transport data but don't want to do OpenID
 304:      * authentication with identifiers.
 305:      *
 306:      * @return Auth_OpenID_AuthRequest $auth_request An object
 307:      * containing the discovered information will be returned, with a
 308:      * method for building a redirect URL to the server, as described
 309:      * in step 3 of the overview. This object may also be used to add
 310:      * extension arguments to the request, using its 'addExtensionArg'
 311:      * method.
 312:      */
 313:     function begin($user_url, $anonymous=false)
 314:     {
 315:         $openid_url = $user_url;
 316: 
 317:         $disco = $this->getDiscoveryObject($this->session,
 318:                                            $openid_url,
 319:                                            $this->session_key_prefix);
 320: 
 321:         // Set the 'stale' attribute of the manager.  If discovery
 322:         // fails in a fatal way, the stale flag will cause the manager
 323:         // to be cleaned up next time discovery is attempted.
 324: 
 325:         $m = $disco->getManager();
 326:         $loader = new Auth_Yadis_ManagerLoader();
 327: 
 328:         if ($m) {
 329:             if ($m->stale) {
 330:                 $disco->destroyManager();
 331:             } else {
 332:                 $m->stale = true;
 333:                 $disco->session->set($disco->session_key,
 334:                                      serialize($loader->toSession($m)));
 335:             }
 336:         }
 337: 
 338:         $endpoint = $disco->getNextService($this->discoverMethod,
 339:                                            $this->consumer->fetcher);
 340: 
 341:         // Reset the 'stale' attribute of the manager.
 342:         $m = $disco->getManager();
 343:         if ($m) {
 344:             $m->stale = false;
 345:             $disco->session->set($disco->session_key,
 346:                                  serialize($loader->toSession($m)));
 347:         }
 348: 
 349:         if ($endpoint === null) {
 350:             return null;
 351:         } else {
 352:             return $this->beginWithoutDiscovery($endpoint,
 353:                                                 $anonymous);
 354:         }
 355:     }
 356: 
 357:     /**
 358:      * Start OpenID verification without doing OpenID server
 359:      * discovery. This method is used internally by Consumer.begin
 360:      * after discovery is performed, and exists to provide an
 361:      * interface for library users needing to perform their own
 362:      * discovery.
 363:      *
 364:      * @param Auth_OpenID_ServiceEndpoint $endpoint an OpenID service
 365:      * endpoint descriptor.
 366:      *
 367:      * @param bool anonymous Set to true if you want to perform OpenID
 368:      * without identifiers.
 369:      *
 370:      * @return Auth_OpenID_AuthRequest $auth_request An OpenID
 371:      * authentication request object.
 372:      */
 373:     function beginWithoutDiscovery($endpoint, $anonymous=false)
 374:     {
 375:         $loader = new Auth_OpenID_ServiceEndpointLoader();
 376:         $auth_req = $this->consumer->begin($endpoint);
 377:         $this->session->set($this->_token_key,
 378:               $loader->toSession($auth_req->endpoint));
 379:         if (!$auth_req->setAnonymous($anonymous)) {
 380:             return new Auth_OpenID_FailureResponse(null,
 381:               "OpenID 1 requests MUST include the identifier " .
 382:               "in the request.");
 383:         }
 384:         return $auth_req;
 385:     }
 386: 
 387:     /**
 388:      * Called to interpret the server's response to an OpenID
 389:      * request. It is called in step 4 of the flow described in the
 390:      * consumer overview.
 391:      *
 392:      * @param string $current_url The URL used to invoke the application.
 393:      * Extract the URL from your application's web
 394:      * request framework and specify it here to have it checked
 395:      * against the openid.current_url value in the response.  If
 396:      * the current_url URL check fails, the status of the
 397:      * completion will be FAILURE.
 398:      *
 399:      * @param array $query An array of the query parameters (key =>
 400:      * value pairs) for this HTTP request.  Defaults to null.  If
 401:      * null, the GET or POST data are automatically gotten from the
 402:      * PHP environment.  It is only useful to override $query for
 403:      * testing.
 404:      *
 405:      * @return Auth_OpenID_ConsumerResponse $response A instance of an
 406:      * Auth_OpenID_ConsumerResponse subclass. The type of response is
 407:      * indicated by the status attribute, which will be one of
 408:      * SUCCESS, CANCEL, FAILURE, or SETUP_NEEDED.
 409:      */
 410:     function complete($current_url, $query=null)
 411:     {
 412:         if ($current_url && !is_string($current_url)) {
 413:             // This is ugly, but we need to complain loudly when
 414:             // someone uses the API incorrectly.
 415:             trigger_error("current_url must be a string; see NEWS file " .
 416:                           "for upgrading notes.",
 417:                           E_USER_ERROR);
 418:         }
 419: 
 420:         if ($query === null) {
 421:             $query = Auth_OpenID::getQuery();
 422:         }
 423: 
 424:         $loader = new Auth_OpenID_ServiceEndpointLoader();
 425:         $endpoint_data = $this->session->get($this->_token_key);
 426:         $endpoint =
 427:             $loader->fromSession($endpoint_data);
 428: 
 429:         $message = Auth_OpenID_Message::fromPostArgs($query);
 430:         $response = $this->consumer->complete($message, $endpoint,
 431:                                               $current_url);
 432:         $this->session->del($this->_token_key);
 433: 
 434:         if (in_array($response->status, array(Auth_OpenID_SUCCESS,
 435:                                               Auth_OpenID_CANCEL))) {
 436:             if ($response->identity_url !== null) {
 437:                 $disco = $this->getDiscoveryObject($this->session,
 438:                                                    $response->identity_url,
 439:                                                    $this->session_key_prefix);
 440:                 $disco->cleanup(true);
 441:             }
 442:         }
 443: 
 444:         return $response;
 445:     }
 446: }
 447: 
 448: /**
 449:  * A class implementing HMAC/DH-SHA1 consumer sessions.
 450:  *
 451:  * @package OpenID
 452:  */
 453: class Auth_OpenID_DiffieHellmanSHA1ConsumerSession {
 454:     var $session_type = 'DH-SHA1';
 455:     var $hash_func = 'Auth_OpenID_SHA1';
 456:     var $secret_size = 20;
 457:     var $allowed_assoc_types = array('HMAC-SHA1');
 458: 
 459:     function Auth_OpenID_DiffieHellmanSHA1ConsumerSession($dh = null)
 460:     {
 461:         if ($dh === null) {
 462:             $dh = new Auth_OpenID_DiffieHellman();
 463:         }
 464: 
 465:         $this->dh = $dh;
 466:     }
 467: 
 468:     function getRequest()
 469:     {
 470:         $math = Auth_OpenID_getMathLib();
 471: 
 472:         $cpub = $math->longToBase64($this->dh->public);
 473: 
 474:         $args = array('dh_consumer_public' => $cpub);
 475: 
 476:         if (!$this->dh->usingDefaultValues()) {
 477:             $args = array_merge($args, array(
 478:                 'dh_modulus' =>
 479:                      $math->longToBase64($this->dh->mod),
 480:                 'dh_gen' =>
 481:                      $math->longToBase64($this->dh->gen)));
 482:         }
 483: 
 484:         return $args;
 485:     }
 486: 
 487:     function extractSecret($response)
 488:     {
 489:         if (!$response->hasKey(Auth_OpenID_OPENID_NS,
 490:                                'dh_server_public')) {
 491:             return null;
 492:         }
 493: 
 494:         if (!$response->hasKey(Auth_OpenID_OPENID_NS,
 495:                                'enc_mac_key')) {
 496:             return null;
 497:         }
 498: 
 499:         $math = Auth_OpenID_getMathLib();
 500: 
 501:         $spub = $math->base64ToLong($response->getArg(Auth_OpenID_OPENID_NS,
 502:                                                       'dh_server_public'));
 503:         $enc_mac_key = base64_decode($response->getArg(Auth_OpenID_OPENID_NS,
 504:                                                        'enc_mac_key'));
 505: 
 506:         return $this->dh->xorSecret($spub, $enc_mac_key, $this->hash_func);
 507:     }
 508: }
 509: 
 510: /**
 511:  * A class implementing HMAC/DH-SHA256 consumer sessions.
 512:  *
 513:  * @package OpenID
 514:  */
 515: class Auth_OpenID_DiffieHellmanSHA256ConsumerSession extends
 516:       Auth_OpenID_DiffieHellmanSHA1ConsumerSession {
 517:     var $session_type = 'DH-SHA256';
 518:     var $hash_func = 'Auth_OpenID_SHA256';
 519:     var $secret_size = 32;
 520:     var $allowed_assoc_types = array('HMAC-SHA256');
 521: }
 522: 
 523: /**
 524:  * A class implementing plaintext consumer sessions.
 525:  *
 526:  * @package OpenID
 527:  */
 528: class Auth_OpenID_PlainTextConsumerSession {
 529:     var $session_type = 'no-encryption';
 530:     var $allowed_assoc_types =  array('HMAC-SHA1', 'HMAC-SHA256');
 531: 
 532:     function getRequest()
 533:     {
 534:         return array();
 535:     }
 536: 
 537:     function extractSecret($response)
 538:     {
 539:         if (!$response->hasKey(Auth_OpenID_OPENID_NS, 'mac_key')) {
 540:             return null;
 541:         }
 542: 
 543:         return base64_decode($response->getArg(Auth_OpenID_OPENID_NS,
 544:                                                'mac_key'));
 545:     }
 546: }
 547: 
 548: /**
 549:  * Returns available session types.
 550:  */
 551: function Auth_OpenID_getAvailableSessionTypes()
 552: {
 553:     $types = array(
 554:       'no-encryption' => 'Auth_OpenID_PlainTextConsumerSession',
 555:       'DH-SHA1' => 'Auth_OpenID_DiffieHellmanSHA1ConsumerSession',
 556:       'DH-SHA256' => 'Auth_OpenID_DiffieHellmanSHA256ConsumerSession');
 557: 
 558:     return $types;
 559: }
 560: 
 561: /**
 562:  * This class is the interface to the OpenID consumer logic.
 563:  * Instances of it maintain no per-request state, so they can be
 564:  * reused (or even used by multiple threads concurrently) as needed.
 565:  *
 566:  * @package OpenID
 567:  */
 568: class Auth_OpenID_GenericConsumer {
 569:     /**
 570:      * @access private
 571:      */
 572:     var $discoverMethod = 'Auth_OpenID_discover';
 573: 
 574:     /**
 575:      * This consumer's store object.
 576:      */
 577:     var $store;
 578: 
 579:     /**
 580:      * @access private
 581:      */
 582:     var $_use_assocs;
 583: 
 584:     /**
 585:      * @access private
 586:      */
 587:     var $openid1_nonce_query_arg_name = 'janrain_nonce';
 588: 
 589:     /**
 590:      * Another query parameter that gets added to the return_to for
 591:      * OpenID 1; if the user's session state is lost, use this claimed
 592:      * identifier to do discovery when verifying the response.
 593:      */
 594:     var $openid1_return_to_identifier_name = 'openid1_claimed_id';
 595: 
 596:     /**
 597:      * This method initializes a new {@link Auth_OpenID_Consumer}
 598:      * instance to access the library.
 599:      *
 600:      * @param Auth_OpenID_OpenIDStore $store This must be an object
 601:      * that implements the interface in {@link Auth_OpenID_OpenIDStore}.
 602:      * Several concrete implementations are provided, to cover most common use
 603:      * cases.  For stores backed by MySQL, PostgreSQL, or SQLite, see
 604:      * the {@link Auth_OpenID_SQLStore} class and its sublcasses.  For a
 605:      * filesystem-backed store, see the {@link Auth_OpenID_FileStore} module.
 606:      * As a last resort, if it isn't possible for the server to store
 607:      * state at all, an instance of {@link Auth_OpenID_DumbStore} can be used.
 608:      *
 609:      * @param bool $immediate This is an optional boolean value.  It
 610:      * controls whether the library uses immediate mode, as explained
 611:      * in the module description.  The default value is False, which
 612:      * disables immediate mode.
 613:      */
 614:     function Auth_OpenID_GenericConsumer($store)
 615:     {
 616:         $this->store = $store;
 617:         $this->negotiator = Auth_OpenID_getDefaultNegotiator();
 618:         $this->_use_assocs = (is_null($this->store) ? false : true);
 619: 
 620:         $this->fetcher = Auth_Yadis_Yadis::getHTTPFetcher();
 621: 
 622:         $this->session_types = Auth_OpenID_getAvailableSessionTypes();
 623:     }
 624: 
 625:     /**
 626:      * Called to begin OpenID authentication using the specified
 627:      * {@link Auth_OpenID_ServiceEndpoint}.
 628:      *
 629:      * @access private
 630:      */
 631:     function begin($service_endpoint)
 632:     {
 633:         $assoc = $this->_getAssociation($service_endpoint);
 634:         $r = new Auth_OpenID_AuthRequest($service_endpoint, $assoc);
 635:         $r->return_to_args[$this->openid1_nonce_query_arg_name] =
 636:             Auth_OpenID_mkNonce();
 637: 
 638:         if ($r->message->isOpenID1()) {
 639:             $r->return_to_args[$this->openid1_return_to_identifier_name] =
 640:                 $r->endpoint->claimed_id;
 641:         }
 642: 
 643:         return $r;
 644:     }
 645: 
 646:     /**
 647:      * Given an {@link Auth_OpenID_Message}, {@link
 648:      * Auth_OpenID_ServiceEndpoint} and optional return_to URL,
 649:      * complete OpenID authentication.
 650:      *
 651:      * @access private
 652:      */
 653:     function complete($message, $endpoint, $return_to)
 654:     {
 655:         $mode = $message->getArg(Auth_OpenID_OPENID_NS, 'mode',
 656:                                  '<no mode set>');
 657: 
 658:         $mode_methods = array(
 659:                               'cancel' => '_complete_cancel',
 660:                               'error' => '_complete_error',
 661:                               'setup_needed' => '_complete_setup_needed',
 662:                               'id_res' => '_complete_id_res',
 663:                               );
 664: 
 665:         $method = Auth_OpenID::arrayGet($mode_methods, $mode,
 666:                                         '_completeInvalid');
 667: 
 668:         return call_user_func_array(array($this, $method),
 669:                                     array($message, &$endpoint, $return_to));
 670:     }
 671: 
 672:     /**
 673:      * @access private
 674:      */
 675:     function _completeInvalid($message, $endpoint, $unused=null)
 676:     {
 677:         $mode = $message->getArg(Auth_OpenID_OPENID_NS, 'mode',
 678:                                  '<No mode set>');
 679: 
 680:         return new Auth_OpenID_FailureResponse($endpoint,
 681:                     sprintf("Invalid openid.mode '%s'", $mode));
 682:     }
 683: 
 684:     /**
 685:      * @access private
 686:      */
 687:     function _complete_cancel($message, $endpoint, $unused)
 688:     {
 689:         return new Auth_OpenID_CancelResponse($endpoint);
 690:     }
 691: 
 692:     /**
 693:      * @access private
 694:      */
 695:     function _complete_error($message, $endpoint, $unused)
 696:     {
 697:         $error = $message->getArg(Auth_OpenID_OPENID_NS, 'error');
 698:         $contact = $message->getArg(Auth_OpenID_OPENID_NS, 'contact');
 699:         $reference = $message->getArg(Auth_OpenID_OPENID_NS, 'reference');
 700: 
 701:         return new Auth_OpenID_FailureResponse($endpoint, $error,
 702:                                                $contact, $reference);
 703:     }
 704: 
 705:     /**
 706:      * @access private
 707:      */
 708:     function _complete_setup_needed($message, $endpoint, $unused)
 709:     {
 710:         if (!$message->isOpenID2()) {
 711:             return $this->_completeInvalid($message, $endpoint);
 712:         }
 713: 
 714:         $user_setup_url = $message->getArg(Auth_OpenID_OPENID2_NS,
 715:                                            'user_setup_url');
 716:         return new Auth_OpenID_SetupNeededResponse($endpoint, $user_setup_url);
 717:     }
 718: 
 719:     /**
 720:      * @access private
 721:      */
 722:     function _complete_id_res($message, $endpoint, $return_to)
 723:     {
 724:         $user_setup_url = $message->getArg(Auth_OpenID_OPENID1_NS,
 725:                                            'user_setup_url');
 726: 
 727:         if ($this->_checkSetupNeeded($message)) {
 728:             return new Auth_OpenID_SetupNeededResponse(
 729:                 $endpoint, $user_setup_url);
 730:         } else {
 731:             return $this->_doIdRes($message, $endpoint, $return_to);
 732:         }
 733:     }
 734: 
 735:     /**
 736:      * @access private
 737:      */
 738:     function _checkSetupNeeded($message)
 739:     {
 740:         // In OpenID 1, we check to see if this is a cancel from
 741:         // immediate mode by the presence of the user_setup_url
 742:         // parameter.
 743:         if ($message->isOpenID1()) {
 744:             $user_setup_url = $message->getArg(Auth_OpenID_OPENID1_NS,
 745:                                                'user_setup_url');
 746:             if ($user_setup_url !== null) {
 747:                 return true;
 748:             }
 749:         }
 750: 
 751:         return false;
 752:     }
 753: 
 754:     /**
 755:      * @access private
 756:      */
 757:     function _doIdRes($message, $endpoint, $return_to)
 758:     {
 759:         // Checks for presence of appropriate fields (and checks
 760:         // signed list fields)
 761:         $result = $this->_idResCheckForFields($message);
 762: 
 763:         if (Auth_OpenID::isFailure($result)) {
 764:             return $result;
 765:         }
 766: 
 767:         if (!$this->_checkReturnTo($message, $return_to)) {
 768:             return new Auth_OpenID_FailureResponse(null,
 769:             sprintf("return_to does not match return URL. Expected %s, got %s",
 770:                     $return_to,
 771:                     $message->getArg(Auth_OpenID_OPENID_NS, 'return_to')));
 772:         }
 773: 
 774:         // Verify discovery information:
 775:         $result = $this->_verifyDiscoveryResults($message, $endpoint);
 776: 
 777:         if (Auth_OpenID::isFailure($result)) {
 778:             return $result;
 779:         }
 780: 
 781:         $endpoint = $result;
 782: 
 783:         $result = $this->_idResCheckSignature($message,
 784:                                               $endpoint->server_url);
 785: 
 786:         if (Auth_OpenID::isFailure($result)) {
 787:             return $result;
 788:         }
 789: 
 790:         $result = $this->_idResCheckNonce($message, $endpoint);
 791: 
 792:         if (Auth_OpenID::isFailure($result)) {
 793:             return $result;
 794:         }
 795: 
 796:         $signed_list_str = $message->getArg(Auth_OpenID_OPENID_NS, 'signed',
 797:                                             Auth_OpenID_NO_DEFAULT);
 798:         if (Auth_OpenID::isFailure($signed_list_str)) {
 799:             return $signed_list_str;
 800:         }
 801:         $signed_list = explode(',', $signed_list_str);
 802: 
 803:         $signed_fields = Auth_OpenID::addPrefix($signed_list, "openid.");
 804: 
 805:         return new Auth_OpenID_SuccessResponse($endpoint, $message,
 806:                                                $signed_fields);
 807: 
 808:     }
 809: 
 810:     /**
 811:      * @access private
 812:      */
 813:     function _checkReturnTo($message, $return_to)
 814:     {
 815:         // Check an OpenID message and its openid.return_to value
 816:         // against a return_to URL from an application.  Return True
 817:         // on success, False on failure.
 818: 
 819:         // Check the openid.return_to args against args in the
 820:         // original message.
 821:         $result = Auth_OpenID_GenericConsumer::_verifyReturnToArgs(
 822:                                            $message->toPostArgs());
 823:         if (Auth_OpenID::isFailure($result)) {
 824:             return false;
 825:         }
 826: 
 827:         // Check the return_to base URL against the one in the
 828:         // message.
 829:         $msg_return_to = $message->getArg(Auth_OpenID_OPENID_NS,
 830:                                           'return_to');
 831:         if (Auth_OpenID::isFailure($return_to)) {
 832:             return false;
 833:         }
 834: 
 835:         $return_to_parts = parse_url(Auth_OpenID_urinorm($return_to));
 836:         $msg_return_to_parts = parse_url(Auth_OpenID_urinorm($msg_return_to));
 837: 
 838:         // If port is absent from both, add it so it's equal in the
 839:         // check below.
 840:         if ((!array_key_exists('port', $return_to_parts)) &&
 841:             (!array_key_exists('port', $msg_return_to_parts))) {
 842:             $return_to_parts['port'] = null;
 843:             $msg_return_to_parts['port'] = null;
 844:         }
 845: 
 846:         // If path is absent from both, add it so it's equal in the
 847:         // check below.
 848:         if ((!array_key_exists('path', $return_to_parts)) &&
 849:             (!array_key_exists('path', $msg_return_to_parts))) {
 850:             $return_to_parts['path'] = null;
 851:             $msg_return_to_parts['path'] = null;
 852:         }
 853: 
 854:         // The URL scheme, authority, and path MUST be the same
 855:         // between the two URLs.
 856:         foreach (array('scheme', 'host', 'port', 'path') as $component) {
 857:             // If the url component is absent in either URL, fail.
 858:             // There should always be a scheme, host, port, and path.
 859:             if (!array_key_exists($component, $return_to_parts)) {
 860:                 return false;
 861:             }
 862: 
 863:             if (!array_key_exists($component, $msg_return_to_parts)) {
 864:                 return false;
 865:             }
 866: 
 867:             if (Auth_OpenID::arrayGet($return_to_parts, $component) !==
 868:                 Auth_OpenID::arrayGet($msg_return_to_parts, $component)) {
 869:                 return false;
 870:             }
 871:         }
 872: 
 873:         return true;
 874:     }
 875: 
 876:     /**
 877:      * @access private
 878:      */
 879:     function _verifyReturnToArgs($query)
 880:     {
 881:         // Verify that the arguments in the return_to URL are present in this
 882:         // response.
 883: 
 884:         $message = Auth_OpenID_Message::fromPostArgs($query);
 885:         $return_to = $message->getArg(Auth_OpenID_OPENID_NS, 'return_to');
 886: 
 887:         if (Auth_OpenID::isFailure($return_to)) {
 888:             return $return_to;
 889:         }
 890:         // this should be checked by _idResCheckForFields
 891:         if (!$return_to) {
 892:             return new Auth_OpenID_FailureResponse(null,
 893:                            "Response has no return_to");
 894:         }
 895: 
 896:         $parsed_url = parse_url($return_to);
 897: 
 898:         $q = array();
 899:         if (array_key_exists('query', $parsed_url)) {
 900:             $rt_query = $parsed_url['query'];
 901:             $q = Auth_OpenID::parse_str($rt_query);
 902:         }
 903: 
 904:         foreach ($q as $rt_key => $rt_value) {
 905:             if (!array_key_exists($rt_key, $query)) {
 906:                 return new Auth_OpenID_FailureResponse(null,
 907:                   sprintf("return_to parameter %s absent from query", $rt_key));
 908:             } else {
 909:                 $value = $query[$rt_key];
 910:                 if ($rt_value != $value) {
 911:                     return new Auth_OpenID_FailureResponse(null,
 912:                       sprintf("parameter %s value %s does not match " .
 913:                               "return_to value %s", $rt_key,
 914:                               $value, $rt_value));
 915:                 }
 916:             }
 917:         }
 918: 
 919:         // Make sure all non-OpenID arguments in the response are also
 920:         // in the signed return_to.
 921:         $bare_args = $message->getArgs(Auth_OpenID_BARE_NS);
 922:         foreach ($bare_args as $key => $value) {
 923:             if (Auth_OpenID::arrayGet($q, $key) != $value) {
 924:                 return new Auth_OpenID_FailureResponse(null,
 925:                   sprintf("Parameter %s = %s not in return_to URL",
 926:                           $key, $value));
 927:             }
 928:         }
 929: 
 930:         return true;
 931:     }
 932: 
 933:     /**
 934:      * @access private
 935:      */
 936:     function _idResCheckSignature($message, $server_url)
 937:     {
 938:         $assoc_handle = $message->getArg(Auth_OpenID_OPENID_NS,
 939:                                          'assoc_handle');
 940:         if (Auth_OpenID::isFailure($assoc_handle)) {
 941:             return $assoc_handle;
 942:         }
 943: 
 944:         $assoc = $this->store->getAssociation($server_url, $assoc_handle);
 945: 
 946:         if ($assoc) {
 947:             if ($assoc->getExpiresIn() <= 0) {
 948:                 // It might be a good idea sometimes to re-start
 949:                 // the authentication with a new association. Doing it
 950:                 // automatically opens the possibility for
 951:                 // denial-of-service by a server that just returns
 952:                 // expired associations (or really short-lived
 953:                 // associations)
 954:                 return new Auth_OpenID_FailureResponse(null,
 955:                              'Association with ' . $server_url . ' expired');
 956:             }
 957: 
 958:             if (!$assoc->checkMessageSignature($message)) {
 959:                 // If we get a "bad signature" here, it means that the association
 960:                 // is unrecoverabley corrupted in some way. Any futher attempts
 961:                 // to login with this association is likely to fail. Drop it.
 962:                 $this->store->removeAssociation($server_url, $assoc_handle);
 963:                 return new Auth_OpenID_FailureResponse(null,
 964:                                                        "Bad signature");
 965:             }
 966:         } else {
 967:             // It's not an association we know about.  Stateless mode
 968:             // is our only possible path for recovery.
 969:             // framework will not want to block on this call to
 970:             // _checkAuth.
 971:             if (!$this->_checkAuth($message, $server_url)) {
 972:                 return new Auth_OpenID_FailureResponse(null,
 973:                              "Server denied check_authentication");
 974:             }
 975:         }
 976: 
 977:         return null;
 978:     }
 979: 
 980:     /**
 981:      * @access private
 982:      */
 983:     function _verifyDiscoveryResults($message, $endpoint=null)
 984:     {
 985:         if ($message->getOpenIDNamespace() == Auth_OpenID_OPENID2_NS) {
 986:             return $this->_verifyDiscoveryResultsOpenID2($message,
 987:                                                          $endpoint);
 988:         } else {
 989:             return $this->_verifyDiscoveryResultsOpenID1($message,
 990:                                                          $endpoint);
 991:         }
 992:     }
 993: 
 994:     /**
 995:      * @access private
 996:      */
 997:     function _verifyDiscoveryResultsOpenID1($message, $endpoint)
 998:     {
 999:         $claimed_id = $message->getArg(Auth_OpenID_BARE_NS,
1000:                                 $this->openid1_return_to_identifier_name);
1001: 
1002:         if (($endpoint === null) && ($claimed_id === null)) {
1003:             return new Auth_OpenID_FailureResponse($endpoint,
1004:               'When using OpenID 1, the claimed ID must be supplied, ' .
1005:               'either by passing it through as a return_to parameter ' .
1006:               'or by using a session, and supplied to the GenericConsumer ' .
1007:               'as the argument to complete()');
1008:         } else if (($endpoint !== null) && ($claimed_id === null)) {
1009:             $claimed_id = $endpoint->claimed_id;
1010:         }
1011: 
1012:         $to_match = new Auth_OpenID_ServiceEndpoint();
1013:         $to_match->type_uris = array(Auth_OpenID_TYPE_1_1);
1014:         $to_match->local_id = $message->getArg(Auth_OpenID_OPENID1_NS,
1015:                                                'identity');
1016: 
1017:         // Restore delegate information from the initiation phase
1018:         $to_match->claimed_id = $claimed_id;
1019: 
1020:         if ($to_match->local_id === null) {
1021:             return new Auth_OpenID_FailureResponse($endpoint,
1022:                          "Missing required field openid.identity");
1023:         }
1024: 
1025:         $to_match_1_0 = $to_match->copy();
1026:         $to_match_1_0->type_uris = array(Auth_OpenID_TYPE_1_0);
1027: 
1028:         if ($endpoint !== null) {
1029:             $result = $this->_verifyDiscoverySingle($endpoint, $to_match);
1030: 
1031:             if (($result instanceof Auth_OpenID_TypeURIMismatch)) {
1032:                 $result = $this->_verifyDiscoverySingle($endpoint,
1033:                                                         $to_match_1_0);
1034:             }
1035: 
1036:             if (Auth_OpenID::isFailure($result)) {
1037:                 // oidutil.log("Error attempting to use stored
1038:                 //             discovery information: " + str(e))
1039:                 //             oidutil.log("Attempting discovery to
1040:                 //             verify endpoint")
1041:             } else {
1042:                 return $endpoint;
1043:             }
1044:         }
1045: 
1046:         // Endpoint is either bad (failed verification) or None
1047:         return $this->_discoverAndVerify($to_match->claimed_id,
1048:                                          array($to_match, $to_match_1_0));
1049:     }
1050: 
1051:     /**
1052:      * @access private
1053:      */
1054:     function _verifyDiscoverySingle($endpoint, $to_match)
1055:     {
1056:         // Every type URI that's in the to_match endpoint has to be
1057:         // present in the discovered endpoint.
1058:         foreach ($to_match->type_uris as $type_uri) {
1059:             if (!$endpoint->usesExtension($type_uri)) {
1060:                 return new Auth_OpenID_TypeURIMismatch($endpoint,
1061:                              "Required type ".$type_uri." not present");
1062:             }
1063:         }
1064: 
1065:         // Fragments do not influence discovery, so we can't compare a
1066:         // claimed identifier with a fragment to discovered
1067:         // information.
1068:         list($defragged_claimed_id, $_) =
1069:             Auth_OpenID::urldefrag($to_match->claimed_id);
1070: 
1071:         if ($defragged_claimed_id != $endpoint->claimed_id) {
1072:             return new Auth_OpenID_FailureResponse($endpoint,
1073:               sprintf('Claimed ID does not match (different subjects!), ' .
1074:                       'Expected %s, got %s', $defragged_claimed_id,
1075:                       $endpoint->claimed_id));
1076:         }
1077: 
1078:         if ($to_match->getLocalID() != $endpoint->getLocalID()) {
1079:             return new Auth_OpenID_FailureResponse($endpoint,
1080:               sprintf('local_id mismatch. Expected %s, got %s',
1081:                       $to_match->getLocalID(), $endpoint->getLocalID()));
1082:         }
1083: 
1084:         // If the server URL is None, this must be an OpenID 1
1085:         // response, because op_endpoint is a required parameter in
1086:         // OpenID 2. In that case, we don't actually care what the
1087:         // discovered server_url is, because signature checking or
1088:         // check_auth should take care of that check for us.
1089:         if ($to_match->server_url === null) {
1090:             if ($to_match->preferredNamespace() != Auth_OpenID_OPENID1_NS) {
1091:                 return new Auth_OpenID_FailureResponse($endpoint,
1092:                              "Preferred namespace mismatch (bug)");
1093:             }
1094:         } else if ($to_match->server_url != $endpoint->server_url) {
1095:             return new Auth_OpenID_FailureResponse($endpoint,
1096:               sprintf('OP Endpoint mismatch. Expected %s, got %s',
1097:                       $to_match->server_url, $endpoint->server_url));
1098:         }
1099: 
1100:         return null;
1101:     }
1102: 
1103:     /**
1104:      * @access private
1105:      */
1106:     function _verifyDiscoveryResultsOpenID2($message, $endpoint)
1107:     {
1108:         $to_match = new Auth_OpenID_ServiceEndpoint();
1109:         $to_match->type_uris = array(Auth_OpenID_TYPE_2_0);
1110:         $to_match->claimed_id = $message->getArg(Auth_OpenID_OPENID2_NS,
1111:                                                  'claimed_id');
1112: 
1113:         $to_match->local_id = $message->getArg(Auth_OpenID_OPENID2_NS,
1114:                                                 'identity');
1115: 
1116:         $to_match->server_url = $message->getArg(Auth_OpenID_OPENID2_NS,
1117:                                                  'op_endpoint');
1118: 
1119:         if ($to_match->server_url === null) {
1120:             return new Auth_OpenID_FailureResponse($endpoint,
1121:                          "OP Endpoint URL missing");
1122:         }
1123: 
1124:         // claimed_id and identifier must both be present or both be
1125:         // absent
1126:         if (($to_match->claimed_id === null) &&
1127:             ($to_match->local_id !== null)) {
1128:             return new Auth_OpenID_FailureResponse($endpoint,
1129:               'openid.identity is present without openid.claimed_id');
1130:         }
1131: 
1132:         if (($to_match->claimed_id !== null) &&
1133:             ($to_match->local_id === null)) {
1134:             return new Auth_OpenID_FailureResponse($endpoint,
1135:               'openid.claimed_id is present without openid.identity');
1136:         }
1137: 
1138:         if ($to_match->claimed_id === null) {
1139:             // This is a response without identifiers, so there's
1140:             // really no checking that we can do, so return an
1141:             // endpoint that's for the specified `openid.op_endpoint'
1142:             return Auth_OpenID_ServiceEndpoint::fromOPEndpointURL(
1143:                                                 $to_match->server_url);
1144:         }
1145: 
1146:         if (!$endpoint) {
1147:             // The claimed ID doesn't match, so we have to do
1148:             // discovery again. This covers not using sessions, OP
1149:             // identifier endpoints and responses that didn't match
1150:             // the original request.
1151:             // oidutil.log('No pre-discovered information supplied.')
1152:             return $this->_discoverAndVerify($to_match->claimed_id,
1153:                                              array($to_match));
1154:         } else {
1155: 
1156:             // The claimed ID matches, so we use the endpoint that we
1157:             // discovered in initiation. This should be the most
1158:             // common case.
1159:             $result = $this->_verifyDiscoverySingle($endpoint, $to_match);
1160: 
1161:             if (Auth_OpenID::isFailure($result)) {
1162:                 $endpoint = $this->_discoverAndVerify($to_match->claimed_id,
1163:                                                       array($to_match));
1164:                 if (Auth_OpenID::isFailure($endpoint)) {
1165:                     return $endpoint;
1166:                 }
1167:             }
1168:         }
1169: 
1170:         // The endpoint we return should have the claimed ID from the
1171:         // message we just verified, fragment and all.
1172:         if ($endpoint->claimed_id != $to_match->claimed_id) {
1173:             $endpoint->claimed_id = $to_match->claimed_id;
1174:         }
1175: 
1176:         return $endpoint;
1177:     }
1178: 
1179:     /**
1180:      * @access private
1181:      */
1182:     function _discoverAndVerify($claimed_id, $to_match_endpoints)
1183:     {
1184:         // oidutil.log('Performing discovery on %s' % (claimed_id,))
1185:         list($unused, $services) = call_user_func($this->discoverMethod,
1186:                                                   $claimed_id,
1187:                                                   $this->fetcher);
1188: 
1189:         if (!$services) {
1190:             return new Auth_OpenID_FailureResponse(null,
1191:               sprintf("No OpenID information found at %s",
1192:                       $claimed_id));
1193:         }
1194: 
1195:         return $this->_verifyDiscoveryServices($claimed_id, $services,
1196:                                                $to_match_endpoints);
1197:     }
1198: 
1199:     /**
1200:      * @access private
1201:      */
1202:     function _verifyDiscoveryServices($claimed_id,
1203:                                       $services, $to_match_endpoints)
1204:     {
1205:         // Search the services resulting from discovery to find one
1206:         // that matches the information from the assertion
1207: 
1208:         foreach ($services as $endpoint) {
1209:             foreach ($to_match_endpoints as $to_match_endpoint) {
1210:                 $result = $this->_verifyDiscoverySingle($endpoint,
1211:                                                         $to_match_endpoint);
1212: 
1213:                 if (!Auth_OpenID::isFailure($result)) {
1214:                     // It matches, so discover verification has
1215:                     // succeeded. Return this endpoint.
1216:                     return $endpoint;
1217:                 }
1218:             }
1219:         }
1220: 
1221:         return new Auth_OpenID_FailureResponse(null,
1222:           sprintf('No matching endpoint found after discovering %s: %s',
1223:                   $claimed_id, $result->message));
1224:     }
1225: 
1226:     /**
1227:      * Extract the nonce from an OpenID 1 response.  Return the nonce
1228:      * from the BARE_NS since we independently check the return_to
1229:      * arguments are the same as those in the response message.
1230:      *
1231:      * See the openid1_nonce_query_arg_name class variable
1232:      *
1233:      * @returns $nonce The nonce as a string or null
1234:      *
1235:      * @access private
1236:      */
1237:     function _idResGetNonceOpenID1($message, $endpoint)
1238:     {
1239:         return $message->getArg(Auth_OpenID_BARE_NS,
1240:                                 $this->openid1_nonce_query_arg_name);
1241:     }
1242: 
1243:     /**
1244:      * @access private
1245:      */
1246:     function _idResCheckNonce($message, $endpoint)
1247:     {
1248:         if ($message->isOpenID1()) {
1249:             // This indicates that the nonce was generated by the consumer
1250:             $nonce = $this->_idResGetNonceOpenID1($message, $endpoint);
1251:             $server_url = '';
1252:         } else {
1253:             $nonce = $message->getArg(Auth_OpenID_OPENID2_NS,
1254:                                       'response_nonce');
1255: 
1256:             $server_url = $endpoint->server_url;
1257:         }
1258: 
1259:         if ($nonce === null) {
1260:             return new Auth_OpenID_FailureResponse($endpoint,
1261:                                      "Nonce missing from response");
1262:         }
1263: 
1264:         $parts = Auth_OpenID_splitNonce($nonce);
1265: 
1266:         if ($parts === null) {
1267:             return new Auth_OpenID_FailureResponse($endpoint,
1268:                                      "Malformed nonce in response");
1269:         }
1270: 
1271:         list($timestamp, $salt) = $parts;
1272: 
1273:         if (!$this->store->useNonce($server_url, $timestamp, $salt)) {
1274:             return new Auth_OpenID_FailureResponse($endpoint,
1275:                          "Nonce already used or out of range");
1276:         }
1277: 
1278:         return null;
1279:     }
1280: 
1281:     /**
1282:      * @access private
1283:      */
1284:     function _idResCheckForFields($message)
1285:     {
1286:         $basic_fields = array('return_to', 'assoc_handle', 'sig', 'signed');
1287:         $basic_sig_fields = array('return_to', 'identity');
1288: 
1289:         $require_fields = array(
1290:             Auth_OpenID_OPENID2_NS => array_merge($basic_fields,
1291:                                                   array('op_endpoint')),
1292: 
1293:             Auth_OpenID_OPENID1_NS => array_merge($basic_fields,
1294:                                                   array('identity'))
1295:             );
1296: 
1297:         $require_sigs = array(
1298:             Auth_OpenID_OPENID2_NS => array_merge($basic_sig_fields,
1299:                                                   array('response_nonce',
1300:                                                         'claimed_id',
1301:                                                         'assoc_handle',
1302:                                                         'op_endpoint')),
1303:             Auth_OpenID_OPENID1_NS => array_merge($basic_sig_fields,
1304:                                                   array('nonce'))
1305:             );
1306: 
1307:         foreach ($require_fields[$message->getOpenIDNamespace()] as $field) {
1308:             if (!$message->hasKey(Auth_OpenID_OPENID_NS, $field)) {
1309:                 return new Auth_OpenID_FailureResponse(null,
1310:                              "Missing required field '".$field."'");
1311:             }
1312:         }
1313: 
1314:         $signed_list_str = $message->getArg(Auth_OpenID_OPENID_NS,
1315:                                             'signed',
1316:                                             Auth_OpenID_NO_DEFAULT);
1317:         if (Auth_OpenID::isFailure($signed_list_str)) {
1318:             return $signed_list_str;
1319:         }
1320:         $signed_list = explode(',', $signed_list_str);
1321: 
1322:         foreach ($require_sigs[$message->getOpenIDNamespace()] as $field) {
1323:             // Field is present and not in signed list
1324:             if ($message->hasKey(Auth_OpenID_OPENID_NS, $field) &&
1325:                 (!in_array($field, $signed_list))) {
1326:                 return new Auth_OpenID_FailureResponse(null,
1327:                              "'".$field."' not signed");
1328:             }
1329:         }
1330: 
1331:         return null;
1332:     }
1333: 
1334:     /**
1335:      * @access private
1336:      */
1337:     function _checkAuth($message, $server_url)
1338:     {
1339:         $request = $this->_createCheckAuthRequest($message);
1340:         if ($request === null) {
1341:             return false;
1342:         }
1343: 
1344:         $resp_message = $this->_makeKVPost($request, $server_url);
1345:         if (($resp_message === null) ||
1346:             (($resp_message instanceof Auth_OpenID_ServerErrorContainer))) {
1347:             return false;
1348:         }
1349: 
1350:         return $this->_processCheckAuthResponse($resp_message, $server_url);
1351:     }
1352: 
1353:     /**
1354:      * @access private
1355:      */
1356:     function _createCheckAuthRequest($message)
1357:     {
1358:         $signed = $message->getArg(Auth_OpenID_OPENID_NS, 'signed');
1359:         if ($signed) {
1360:             foreach (explode(',', $signed) as $k) {
1361:                 $value = $message->getAliasedArg($k);
1362:                 if ($value === null) {
1363:                     return null;
1364:                 }
1365:             }
1366:         }
1367:         $ca_message = $message->copy();
1368:         $ca_message->setArg(Auth_OpenID_OPENID_NS, 'mode',
1369:                             'check_authentication');
1370:         return $ca_message;
1371:     }
1372: 
1373:     /**
1374:      * @access private
1375:      */
1376:     function _processCheckAuthResponse($response, $server_url)
1377:     {
1378:         $is_valid = $response->getArg(Auth_OpenID_OPENID_NS, 'is_valid',
1379:                                       'false');
1380: 
1381:         $invalidate_handle = $response->getArg(Auth_OpenID_OPENID_NS,
1382:                                                'invalidate_handle');
1383: 
1384:         if ($invalidate_handle !== null) {
1385:             $this->store->removeAssociation($server_url,
1386:                                             $invalidate_handle);
1387:         }
1388: 
1389:         if ($is_valid == 'true') {
1390:             return true;
1391:         }
1392: 
1393:         return false;
1394:     }
1395: 
1396:     /**
1397:      * Adapt a POST response to a Message.
1398:      *
1399:      * @param $response Result of a POST to an OpenID endpoint.
1400:      *
1401:      * @access private
1402:      */
1403:     static function _httpResponseToMessage($response, $server_url)
1404:     {
1405:         // Should this function be named Message.fromHTTPResponse instead?
1406:         $response_message = Auth_OpenID_Message::fromKVForm($response->body);
1407: 
1408:         if ($response->status == 400) {
1409:             return Auth_OpenID_ServerErrorContainer::fromMessage(
1410:                         $response_message);
1411:         } else if ($response->status != 200 and $response->status != 206) {
1412:             return null;
1413:         }
1414: 
1415:         return $response_message;
1416:     }
1417: 
1418:     /**
1419:      * @access private
1420:      */
1421:     function _makeKVPost($message, $server_url)
1422:     {
1423:         $body = $message->toURLEncoded();
1424:         $resp = $this->fetcher->post($server_url, $body);
1425: 
1426:         if ($resp === null) {
1427:             return null;
1428:         }
1429: 
1430:         return $this->_httpResponseToMessage($resp, $server_url);
1431:     }
1432: 
1433:     /**
1434:      * @access private
1435:      */
1436:     function _getAssociation($endpoint)
1437:     {
1438:         if (!$this->_use_assocs) {
1439:             return null;
1440:         }
1441: 
1442:         $assoc = $this->store->getAssociation($endpoint->server_url);
1443: 
1444:         if (($assoc === null) ||
1445:             ($assoc->getExpiresIn() <= 0)) {
1446: 
1447:             $assoc = $this->_negotiateAssociation($endpoint);
1448: 
1449:             if ($assoc !== null) {
1450:                 $this->store->storeAssociation($endpoint->server_url,
1451:                                                $assoc);
1452:             }
1453:         }
1454: 
1455:         return $assoc;
1456:     }
1457: 
1458:     /**
1459:      * Handle ServerErrors resulting from association requests.
1460:      *
1461:      * @return $result If server replied with an C{unsupported-type}
1462:      * error, return a tuple of supported C{association_type},
1463:      * C{session_type}.  Otherwise logs the error and returns null.
1464:      *
1465:      * @access private
1466:      */
1467:     function _extractSupportedAssociationType($server_error, $endpoint,
1468:                                               $assoc_type)
1469:     {
1470:         // Any error message whose code is not 'unsupported-type'
1471:         // should be considered a total failure.
1472:         if (($server_error->error_code != 'unsupported-type') ||
1473:             ($server_error->message->isOpenID1())) {
1474:             return null;
1475:         }
1476: 
1477:         // The server didn't like the association/session type that we
1478:         // sent, and it sent us back a message that might tell us how
1479:         // to handle it.
1480: 
1481:         // Extract the session_type and assoc_type from the error
1482:         // message
1483:         $assoc_type = $server_error->message->getArg(Auth_OpenID_OPENID_NS,
1484:                                                      'assoc_type');
1485: 
1486:         $session_type = $server_error->message->getArg(Auth_OpenID_OPENID_NS,
1487:                                                        'session_type');
1488: 
1489:         if (($assoc_type === null) || ($session_type === null)) {
1490:             return null;
1491:         } else if (!$this->negotiator->isAllowed($assoc_type,
1492:                                                  $session_type)) {
1493:             return null;
1494:         } else {
1495:           return array($assoc_type, $session_type);
1496:         }
1497:     }
1498: 
1499:     /**
1500:      * @access private
1501:      */
1502:     function _negotiateAssociation($endpoint)
1503:     {
1504:         // Get our preferred session/association type from the negotiatior.
1505:         list($assoc_type, $session_type) = $this->negotiator->getAllowedType();
1506: 
1507:         $assoc = $this->_requestAssociation(
1508:                            $endpoint, $assoc_type, $session_type);
1509: 
1510:         if (Auth_OpenID::isFailure($assoc)) {
1511:             return null;
1512:         }
1513: 
1514:         if (($assoc instanceof Auth_OpenID_ServerErrorContainer)) {
1515:             $why = $assoc;
1516: 
1517:             $supportedTypes = $this->_extractSupportedAssociationType(
1518:                                      $why, $endpoint, $assoc_type);
1519: 
1520:             if ($supportedTypes !== null) {
1521:                 list($assoc_type, $session_type) = $supportedTypes;
1522: 
1523:                 // Attempt to create an association from the assoc_type
1524:                 // and session_type that the server told us it
1525:                 // supported.
1526:                 $assoc = $this->_requestAssociation(
1527:                                    $endpoint, $assoc_type, $session_type);
1528: 
1529:                 if (($assoc instanceof Auth_OpenID_ServerErrorContainer)) {
1530:                     // Do not keep trying, since it rejected the
1531:                     // association type that it told us to use.
1532:                     // oidutil.log('Server %s refused its suggested association
1533:                     //             'type: session_type=%s, assoc_type=%s'
1534:                     //             % (endpoint.server_url, session_type,
1535:                     //                assoc_type))
1536:                     return null;
1537:                 } else {
1538:                     return $assoc;
1539:                 }
1540:             } else {
1541:                 return null;
1542:             }
1543:         } else {
1544:             return $assoc;
1545:         }
1546:     }
1547: 
1548:     /**
1549:      * @access private
1550:      */
1551:     function _requestAssociation($endpoint, $assoc_type, $session_type)
1552:     {
1553:         list($assoc_session, $args) = $this->_createAssociateRequest(
1554:                                       $endpoint, $assoc_type, $session_type);
1555: 
1556:         $response_message = $this->_makeKVPost($args, $endpoint->server_url);
1557: 
1558:         if ($response_message === null) {
1559:             // oidutil.log('openid.associate request failed: %s' % (why[0],))
1560:             return null;
1561:         } else if (($response_message instanceof Auth_OpenID_ServerErrorContainer)) {
1562:             return $response_message;
1563:         }
1564: 
1565:         return $this->_extractAssociation($response_message, $assoc_session);
1566:     }
1567: 
1568:     /**
1569:      * @access private
1570:      */
1571:     function _extractAssociation($assoc_response, $assoc_session)
1572:     {
1573:         // Extract the common fields from the response, raising an
1574:         // exception if they are not found
1575:         $assoc_type = $assoc_response->getArg(
1576:                          Auth_OpenID_OPENID_NS, 'assoc_type',
1577:                          Auth_OpenID_NO_DEFAULT);
1578: 
1579:         if (Auth_OpenID::isFailure($assoc_type)) {
1580:             return $assoc_type;
1581:         }
1582: 
1583:         $assoc_handle = $assoc_response->getArg(
1584:                            Auth_OpenID_OPENID_NS, 'assoc_handle',
1585:                            Auth_OpenID_NO_DEFAULT);
1586: 
1587:         if (Auth_OpenID::isFailure($assoc_handle)) {
1588:             return $assoc_handle;
1589:         }
1590: 
1591:         // expires_in is a base-10 string. The Python parsing will
1592:         // accept literals that have whitespace around them and will
1593:         // accept negative values. Neither of these are really in-spec,
1594:         // but we think it's OK to accept them.
1595:         $expires_in_str = $assoc_response->getArg(
1596:                              Auth_OpenID_OPENID_NS, 'expires_in',
1597:                              Auth_OpenID_NO_DEFAULT);
1598: 
1599:         if (Auth_OpenID::isFailure($expires_in_str)) {
1600:             return $expires_in_str;
1601:         }
1602: 
1603:         $expires_in = Auth_OpenID::intval($expires_in_str);
1604:         if ($expires_in === false) {
1605: 
1606:             $err = sprintf("Could not parse expires_in from association ".
1607:                            "response %s", print_r($assoc_response, true));
1608:             return new Auth_OpenID_FailureResponse(null, $err);
1609:         }
1610: 
1611:         // OpenID 1 has funny association session behaviour.
1612:         if ($assoc_response->isOpenID1()) {
1613:             $session_type = $this->_getOpenID1SessionType($assoc_response);
1614:         } else {
1615:             $session_type = $assoc_response->getArg(
1616:                                Auth_OpenID_OPENID2_NS, 'session_type',
1617:                                Auth_OpenID_NO_DEFAULT);
1618: 
1619:             if (Auth_OpenID::isFailure($session_type)) {
1620:                 return $session_type;
1621:             }
1622:         }
1623: 
1624:         // Session type mismatch
1625:         if ($assoc_session->session_type != $session_type) {
1626:             if ($assoc_response->isOpenID1() &&
1627:                 ($session_type == 'no-encryption')) {
1628:                 // In OpenID 1, any association request can result in
1629:                 // a 'no-encryption' association response. Setting
1630:                 // assoc_session to a new no-encryption session should
1631:                 // make the rest of this function work properly for
1632:                 // that case.
1633:                 $assoc_session = new Auth_OpenID_PlainTextConsumerSession();
1634:             } else {
1635:                 // Any other mismatch, regardless of protocol version
1636:                 // results in the failure of the association session
1637:                 // altogether.
1638:                 return null;
1639:             }
1640:         }
1641: 
1642:         // Make sure assoc_type is valid for session_type
1643:         if (!in_array($assoc_type, $assoc_session->allowed_assoc_types)) {
1644:             return null;
1645:         }
1646: 
1647:         // Delegate to the association session to extract the secret
1648:         // from the response, however is appropriate for that session
1649:         // type.
1650:         $secret = $assoc_session->extractSecret($assoc_response);
1651: 
1652:         if ($secret === null) {
1653:             return null;
1654:         }
1655: 
1656:         return Auth_OpenID_Association::fromExpiresIn(
1657:                  $expires_in, $assoc_handle, $secret, $assoc_type);
1658:     }
1659: 
1660:     /**
1661:      * @access private
1662:      */
1663:     function _createAssociateRequest($endpoint, $assoc_type, $session_type)
1664:     {
1665:         if (array_key_exists($session_type, $this->session_types)) {
1666:             $session_type_class = $this->session_types[$session_type];
1667: 
1668:             if (is_callable($session_type_class)) {
1669:                 $assoc_session = $session_type_class();
1670:             } else {
1671:                 $assoc_session = new $session_type_class();
1672:             }
1673:         } else {
1674:             return null;
1675:         }
1676: 
1677:         $args = array(
1678:             'mode' => 'associate',
1679:             'assoc_type' => $assoc_type);
1680: 
1681:         if (!$endpoint->compatibilityMode()) {
1682:             $args['ns'] = Auth_OpenID_OPENID2_NS;
1683:         }
1684: 
1685:         // Leave out the session type if we're in compatibility mode
1686:         // *and* it's no-encryption.
1687:         if ((!$endpoint->compatibilityMode()) ||
1688:             ($assoc_session->session_type != 'no-encryption')) {
1689:             $args['session_type'] = $assoc_session->session_type;
1690:         }
1691: 
1692:         $args = array_merge($args, $assoc_session->getRequest());
1693:         $message = Auth_OpenID_Message::fromOpenIDArgs($args);
1694:         return array($assoc_session, $message);
1695:     }
1696: 
1697:     /**
1698:      * Given an association response message, extract the OpenID 1.X
1699:      * session type.
1700:      *
1701:      * This function mostly takes care of the 'no-encryption' default
1702:      * behavior in OpenID 1.
1703:      *
1704:      * If the association type is plain-text, this function will
1705:      * return 'no-encryption'
1706:      *
1707:      * @access private
1708:      * @return $typ The association type for this message
1709:      */
1710:     function _getOpenID1SessionType($assoc_response)
1711:     {
1712:         // If it's an OpenID 1 message, allow session_type to default
1713:         // to None (which signifies "no-encryption")
1714:         $session_type = $assoc_response->getArg(Auth_OpenID_OPENID1_NS,
1715:                                                 'session_type');
1716: 
1717:         // Handle the differences between no-encryption association
1718:         // respones in OpenID 1 and 2:
1719: 
1720:         // no-encryption is not really a valid session type for OpenID
1721:         // 1, but we'll accept it anyway, while issuing a warning.
1722:         if ($session_type == 'no-encryption') {
1723:             // oidutil.log('WARNING: OpenID server sent "no-encryption"'
1724:             //             'for OpenID 1.X')
1725:         } else if (($session_type == '') || ($session_type === null)) {
1726:             // Missing or empty session type is the way to flag a
1727:             // 'no-encryption' response. Change the session type to
1728:             // 'no-encryption' so that it can be handled in the same
1729:             // way as OpenID 2 'no-encryption' respones.
1730:             $session_type = 'no-encryption';
1731:         }
1732: 
1733:         return $session_type;
1734:     }
1735: }
1736: 
1737: /**
1738:  * This class represents an authentication request from a consumer to
1739:  * an OpenID server.
1740:  *
1741:  * @package OpenID
1742:  */
1743: class Auth_OpenID_AuthRequest {
1744: 
1745:     /**
1746:      * Initialize an authentication request with the specified token,
1747:      * association, and endpoint.
1748:      *
1749:      * Users of this library should not create instances of this
1750:      * class.  Instances of this class are created by the library when
1751:      * needed.
1752:      */
1753:     function Auth_OpenID_AuthRequest($endpoint, $assoc)
1754:     {
1755:         $this->assoc = $assoc;
1756:         $this->endpoint = $endpoint;
1757:         $this->return_to_args = array();
1758:         $this->message = new Auth_OpenID_Message(
1759:             $endpoint->preferredNamespace());
1760:         $this->_anonymous = false;
1761:     }
1762: 
1763:     /**
1764:      * Add an extension to this checkid request.
1765:      *
1766:      * $extension_request: An object that implements the extension
1767:      * request interface for adding arguments to an OpenID message.
1768:      */
1769:     function addExtension($extension_request)
1770:     {
1771:         $extension_request->toMessage($this->message);
1772:     }
1773: 
1774:     /**
1775:      * Add an extension argument to this OpenID authentication
1776:      * request.
1777:      *
1778:      * Use caution when adding arguments, because they will be
1779:      * URL-escaped and appended to the redirect URL, which can easily
1780:      * get quite long.
1781:      *
1782:      * @param string $namespace The namespace for the extension. For
1783:      * example, the simple registration extension uses the namespace
1784:      * 'sreg'.
1785:      *
1786:      * @param string $key The key within the extension namespace. For
1787:      * example, the nickname field in the simple registration
1788:      * extension's key is 'nickname'.
1789:      *
1790:      * @param string $value The value to provide to the server for
1791:      * this argument.
1792:      */
1793:     function addExtensionArg($namespace, $key, $value)
1794:     {
1795:         return $this->message->setArg($namespace, $key, $value);
1796:     }
1797: 
1798:     /**
1799:      * Set whether this request should be made anonymously. If a
1800:      * request is anonymous, the identifier will not be sent in the
1801:      * request. This is only useful if you are making another kind of
1802:      * request with an extension in this request.
1803:      *
1804:      * Anonymous requests are not allowed when the request is made
1805:      * with OpenID 1.
1806:      */
1807:     function setAnonymous($is_anonymous)
1808:     {
1809:         if ($is_anonymous && $this->message->isOpenID1()) {
1810:             return false;
1811:         } else {
1812:             $this->_anonymous = $is_anonymous;
1813:             return true;
1814:         }
1815:     }
1816: 
1817:     /**
1818:      * Produce a {@link Auth_OpenID_Message} representing this
1819:      * request.
1820:      *
1821:      * @param string $realm The URL (or URL pattern) that identifies
1822:      * your web site to the user when she is authorizing it.
1823:      *
1824:      * @param string $return_to The URL that the OpenID provider will
1825:      * send the user back to after attempting to verify her identity.
1826:      *
1827:      * Not specifying a return_to URL means that the user will not be
1828:      * returned to the site issuing the request upon its completion.
1829:      *
1830:      * @param bool $immediate If true, the OpenID provider is to send
1831:      * back a response immediately, useful for behind-the-scenes
1832:      * authentication attempts.  Otherwise the OpenID provider may
1833:      * engage the user before providing a response.  This is the
1834:      * default case, as the user may need to provide credentials or
1835:      * approve the request before a positive response can be sent.
1836:      */
1837:     function getMessage($realm, $return_to=null, $immediate=false)
1838:     {
1839:         if ($return_to) {
1840:             $return_to = Auth_OpenID::appendArgs($return_to,
1841:                                                  $this->return_to_args);
1842:         } else if ($immediate) {
1843:             // raise ValueError(
1844:             //     '"return_to" is mandatory when
1845:             //using "checkid_immediate"')
1846:             return new Auth_OpenID_FailureResponse(null,
1847:               "'return_to' is mandatory when using checkid_immediate");
1848:         } else if ($this->message->isOpenID1()) {
1849:             // raise ValueError('"return_to" is
1850:             // mandatory for OpenID 1 requests')
1851:             return new Auth_OpenID_FailureResponse(null,
1852:               "'return_to' is mandatory for OpenID 1 requests");
1853:         } else if ($this->return_to_args) {
1854:             // raise ValueError('extra "return_to" arguments
1855:             // were specified, but no return_to was specified')
1856:             return new Auth_OpenID_FailureResponse(null,
1857:               "extra 'return_to' arguments where specified, " .
1858:               "but no return_to was specified");
1859:         }
1860: 
1861:         if ($immediate) {
1862:             $mode = 'checkid_immediate';
1863:         } else {
1864:             $mode = 'checkid_setup';
1865:         }
1866: 
1867:         $message = $this->message->copy();
1868:         if ($message->isOpenID1()) {
1869:             $realm_key = 'trust_root';
1870:         } else {
1871:             $realm_key = 'realm';
1872:         }
1873: 
1874:         $message->updateArgs(Auth_OpenID_OPENID_NS,
1875:                              array(
1876:                                    $realm_key => $realm,
1877:                                    'mode' => $mode,
1878:                                    'return_to' => $return_to));
1879: 
1880:         if (!$this->_anonymous) {
1881:             if ($this->endpoint->isOPIdentifier()) {
1882:                 // This will never happen when we're in compatibility
1883:                 // mode, as long as isOPIdentifier() returns False
1884:                 // whenever preferredNamespace() returns OPENID1_NS.
1885:                 $claimed_id = $request_identity =
1886:                     Auth_OpenID_IDENTIFIER_SELECT;
1887:             } else {
1888:                 $request_identity = $this->endpoint->getLocalID();
1889:                 $claimed_id = $this->endpoint->claimed_id;
1890:             }
1891: 
1892:             // This is true for both OpenID 1 and 2
1893:             $message->setArg(Auth_OpenID_OPENID_NS, 'identity',
1894:                              $request_identity);
1895: 
1896:             if ($message->isOpenID2()) {
1897:                 $message->setArg(Auth_OpenID_OPENID2_NS, 'claimed_id',
1898:                                  $claimed_id);
1899:             }
1900:         }
1901: 
1902:         if ($this->assoc) {
1903:             $message->setArg(Auth_OpenID_OPENID_NS, 'assoc_handle',
1904:                              $this->assoc->handle);
1905:         }
1906: 
1907:         return $message;
1908:     }
1909: 
1910:     function redirectURL($realm, $return_to = null,
1911:                          $immediate = false)
1912:     {
1913:         $message = $this->getMessage($realm, $return_to, $immediate);
1914: 
1915:         if (Auth_OpenID::isFailure($message)) {
1916:             return $message;
1917:         }
1918: 
1919:         return $message->toURL($this->endpoint->server_url);
1920:     }
1921: 
1922:     /**
1923:      * Get html for a form to submit this request to the IDP.
1924:      *
1925:      * form_tag_attrs: An array of attributes to be added to the form
1926:      * tag. 'accept-charset' and 'enctype' have defaults that can be
1927:      * overridden. If a value is supplied for 'action' or 'method', it
1928:      * will be replaced.
1929:      */
1930:     function formMarkup($realm, $return_to=null, $immediate=false,
1931:                         $form_tag_attrs=null)
1932:     {
1933:         $message = $this->getMessage($realm, $return_to, $immediate);
1934: 
1935:         if (Auth_OpenID::isFailure($message)) {
1936:             return $message;
1937:         }
1938: 
1939:         return $message->toFormMarkup($this->endpoint->server_url,
1940:                                       $form_tag_attrs);
1941:     }
1942: 
1943:     /**
1944:      * Get a complete html document that will autosubmit the request
1945:      * to the IDP.
1946:      *
1947:      * Wraps formMarkup.  See the documentation for that function.
1948:      */
1949:     function htmlMarkup($realm, $return_to=null, $immediate=false,
1950:                         $form_tag_attrs=null)
1951:     {
1952:         $form = $this->formMarkup($realm, $return_to, $immediate,
1953:                                   $form_tag_attrs);
1954: 
1955:         if (Auth_OpenID::isFailure($form)) {
1956:             return $form;
1957:         }
1958:         return Auth_OpenID::autoSubmitHTML($form);
1959:     }
1960: 
1961:     function shouldSendRedirect()
1962:     {
1963:         return $this->endpoint->compatibilityMode();
1964:     }
1965: }
1966: 
1967: /**
1968:  * The base class for responses from the Auth_OpenID_Consumer.
1969:  *
1970:  * @package OpenID
1971:  */
1972: class Auth_OpenID_ConsumerResponse {
1973:     var $status = null;
1974: 
1975:     function setEndpoint($endpoint)
1976:     {
1977:         $this->endpoint = $endpoint;
1978:         if ($endpoint === null) {
1979:             $this->identity_url = null;
1980:         } else {
1981:             $this->identity_url = $endpoint->claimed_id;
1982:         }
1983:     }
1984: 
1985:     /**
1986:      * Return the display identifier for this response.
1987:      *
1988:      * The display identifier is related to the Claimed Identifier, but the
1989:      * two are not always identical.  The display identifier is something the
1990:      * user should recognize as what they entered, whereas the response's
1991:      * claimed identifier (in the identity_url attribute) may have extra
1992:      * information for better persistence.
1993:      *
1994:      * URLs will be stripped of their fragments for display.  XRIs will
1995:      * display the human-readable identifier (i-name) instead of the
1996:      * persistent identifier (i-number).
1997:      *
1998:      * Use the display identifier in your user interface.  Use
1999:      * identity_url for querying your database or authorization server.
2000:      *
2001:      */
2002:     function getDisplayIdentifier()
2003:     {
2004:         if ($this->endpoint !== null) {
2005:             return $this->endpoint->getDisplayIdentifier();
2006:         }
2007:         return null;
2008:     }
2009: }
2010: 
2011: /**
2012:  * A response with a status of Auth_OpenID_SUCCESS. Indicates that
2013:  * this request is a successful acknowledgement from the OpenID server
2014:  * that the supplied URL is, indeed controlled by the requesting
2015:  * agent.  This has three relevant attributes:
2016:  *
2017:  * claimed_id - The identity URL that has been authenticated
2018:  *
2019:  * signed_args - The arguments in the server's response that were
2020:  * signed and verified.
2021:  *
2022:  * status - Auth_OpenID_SUCCESS.
2023:  *
2024:  * @package OpenID
2025:  */
2026: class Auth_OpenID_SuccessResponse extends Auth_OpenID_ConsumerResponse {
2027:     var $status = Auth_OpenID_SUCCESS;
2028: 
2029:     /**
2030:      * @access private
2031:      */
2032:     function Auth_OpenID_SuccessResponse($endpoint, $message, $signed_args=null)
2033:     {
2034:         $this->endpoint = $endpoint;
2035:         $this->identity_url = $endpoint->claimed_id;
2036:         $this->signed_args = $signed_args;
2037:         $this->message = $message;
2038: 
2039:         if ($this->signed_args === null) {
2040:             $this->signed_args = array();
2041:         }
2042:     }
2043: 
2044:     /**
2045:      * Extract signed extension data from the server's response.
2046:      *
2047:      * @param string $prefix The extension namespace from which to
2048:      * extract the extension data.
2049:      */
2050:     function extensionResponse($namespace_uri, $require_signed)
2051:     {
2052:         if ($require_signed) {
2053:             return $this->getSignedNS($namespace_uri);
2054:         } else {
2055:             return $this->message->getArgs($namespace_uri);
2056:         }
2057:     }
2058: 
2059:     function isOpenID1()
2060:     {
2061:         return $this->message->isOpenID1();
2062:     }
2063: 
2064:     function isSigned($ns_uri, $ns_key)
2065:     {
2066:         // Return whether a particular key is signed, regardless of
2067:         // its namespace alias
2068:         return in_array($this->message->getKey($ns_uri, $ns_key),
2069:                         $this->signed_args);
2070:     }
2071: 
2072:     function getSigned($ns_uri, $ns_key, $default = null)
2073:     {
2074:         // Return the specified signed field if available, otherwise
2075:         // return default
2076:         if ($this->isSigned($ns_uri, $ns_key)) {
2077:             return $this->message->getArg($ns_uri, $ns_key, $default);
2078:         } else {
2079:             return $default;
2080:         }
2081:     }
2082: 
2083:     function getSignedNS($ns_uri)
2084:     {
2085:         $args = array();
2086: 
2087:         $msg_args = $this->message->getArgs($ns_uri);
2088:         if (Auth_OpenID::isFailure($msg_args)) {
2089:             return null;
2090:         }
2091: 
2092:         foreach ($msg_args as $key => $value) {
2093:             if (!$this->isSigned($ns_uri, $key)) {
2094:                 unset($msg_args[$key]);
2095:             }
2096:         }
2097: 
2098:         return $msg_args;
2099:     }
2100: 
2101:     /**
2102:      * Get the openid.return_to argument from this response.
2103:      *
2104:      * This is useful for verifying that this request was initiated by
2105:      * this consumer.
2106:      *
2107:      * @return string $return_to The return_to URL supplied to the
2108:      * server on the initial request, or null if the response did not
2109:      * contain an 'openid.return_to' argument.
2110:     */
2111:     function getReturnTo()
2112:     {
2113:         return $this->getSigned(Auth_OpenID_OPENID_NS, 'return_to');
2114:     }
2115: }
2116: 
2117: /**
2118:  * A response with a status of Auth_OpenID_FAILURE. Indicates that the
2119:  * OpenID protocol has failed. This could be locally or remotely
2120:  * triggered.  This has three relevant attributes:
2121:  *
2122:  * claimed_id - The identity URL for which authentication was
2123:  * attempted, if it can be determined.  Otherwise, null.
2124:  *
2125:  * message - A message indicating why the request failed, if one is
2126:  * supplied.  Otherwise, null.
2127:  *
2128:  * status - Auth_OpenID_FAILURE.
2129:  *
2130:  * @package OpenID
2131:  */
2132: class Auth_OpenID_FailureResponse extends Auth_OpenID_ConsumerResponse {
2133:     var $status = Auth_OpenID_FAILURE;
2134: 
2135:     function Auth_OpenID_FailureResponse($endpoint, $message = null,
2136:                                          $contact = null, $reference = null)
2137:     {
2138:         $this->setEndpoint($endpoint);
2139:         $this->message = $message;
2140:         $this->contact = $contact;
2141:         $this->reference = $reference;
2142:     }
2143: }
2144: 
2145: /**
2146:  * A specific, internal failure used to detect type URI mismatch.
2147:  *
2148:  * @package OpenID
2149:  */
2150: class Auth_OpenID_TypeURIMismatch extends Auth_OpenID_FailureResponse {
2151: }
2152: 
2153: /**
2154:  * Exception that is raised when the server returns a 400 response
2155:  * code to a direct request.
2156:  *
2157:  * @package OpenID
2158:  */
2159: class Auth_OpenID_ServerErrorContainer {
2160:     function Auth_OpenID_ServerErrorContainer($error_text,
2161:                                               $error_code,
2162:                                               $message)
2163:     {
2164:         $this->error_text = $error_text;
2165:         $this->error_code = $error_code;
2166:         $this->message = $message;
2167:     }
2168: 
2169:     /**
2170:      * @access private
2171:      */
2172:     static function fromMessage($message)
2173:     {
2174:         $error_text = $message->getArg(
2175:            Auth_OpenID_OPENID_NS, 'error', '<no error message supplied>');
2176:         $error_code = $message->getArg(Auth_OpenID_OPENID_NS, 'error_code');
2177:         return new Auth_OpenID_ServerErrorContainer($error_text,
2178:                                                     $error_code,
2179:                                                     $message);
2180:     }
2181: }
2182: 
2183: /**
2184:  * A response with a status of Auth_OpenID_CANCEL. Indicates that the
2185:  * user cancelled the OpenID authentication request.  This has two
2186:  * relevant attributes:
2187:  *
2188:  * claimed_id - The identity URL for which authentication was
2189:  * attempted, if it can be determined.  Otherwise, null.
2190:  *
2191:  * status - Auth_OpenID_SUCCESS.
2192:  *
2193:  * @package OpenID
2194:  */
2195: class Auth_OpenID_CancelResponse extends Auth_OpenID_ConsumerResponse {
2196:     var $status = Auth_OpenID_CANCEL;
2197: 
2198:     function Auth_OpenID_CancelResponse($endpoint)
2199:     {
2200:         $this->setEndpoint($endpoint);
2201:     }
2202: }
2203: 
2204: /**
2205:  * A response with a status of Auth_OpenID_SETUP_NEEDED. Indicates
2206:  * that the request was in immediate mode, and the server is unable to
2207:  * authenticate the user without further interaction.
2208:  *
2209:  * claimed_id - The identity URL for which authentication was
2210:  * attempted.
2211:  *
2212:  * setup_url - A URL that can be used to send the user to the server
2213:  * to set up for authentication. The user should be redirected in to
2214:  * the setup_url, either in the current window or in a new browser
2215:  * window.  Null in OpenID 2.
2216:  *
2217:  * status - Auth_OpenID_SETUP_NEEDED.
2218:  *
2219:  * @package OpenID
2220:  */
2221: class Auth_OpenID_SetupNeededResponse extends Auth_OpenID_ConsumerResponse {
2222:     var $status = Auth_OpenID_SETUP_NEEDED;
2223: 
2224:     function Auth_OpenID_SetupNeededResponse($endpoint,
2225:                                              $setup_url = null)
2226:     {
2227:         $this->setEndpoint($endpoint);
2228:         $this->setup_url = $setup_url;
2229:     }
2230: }
2231: 
2232: 
2233: 
Zenphoto doc API documentation generated by ApiGen