Initial check-in of the service side components of Casa Auth Token
Authentication.
This commit is contained in:
parent
1387827d5f
commit
7382c46b60
8
auth_token/server/CasaAuthServer/.classpath
Normal file
8
auth_token/server/CasaAuthServer/.classpath
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<classpath>
|
||||||
|
<classpathentry kind="src" path="src"/>
|
||||||
|
<classpathentry kind="con" path="org.eclipse.jst.j2ee.internal.web.container"/>
|
||||||
|
<classpathentry kind="lib" path="/usr/share/java/servletapi5.jar"/>
|
||||||
|
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
|
||||||
|
<classpathentry kind="output" path="build/classes"/>
|
||||||
|
</classpath>
|
35
auth_token/server/CasaAuthServer/.project
Normal file
35
auth_token/server/CasaAuthServer/.project
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<projectDescription>
|
||||||
|
<name>CasaAuthServer</name>
|
||||||
|
<comment></comment>
|
||||||
|
<projects>
|
||||||
|
</projects>
|
||||||
|
<buildSpec>
|
||||||
|
<buildCommand>
|
||||||
|
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||||
|
<arguments>
|
||||||
|
</arguments>
|
||||||
|
</buildCommand>
|
||||||
|
<buildCommand>
|
||||||
|
<name>org.eclipse.wst.common.project.facet.core.builder</name>
|
||||||
|
<arguments>
|
||||||
|
</arguments>
|
||||||
|
</buildCommand>
|
||||||
|
<buildCommand>
|
||||||
|
<name>org.eclipse.wst.validation.validationbuilder</name>
|
||||||
|
<arguments>
|
||||||
|
</arguments>
|
||||||
|
</buildCommand>
|
||||||
|
<buildCommand>
|
||||||
|
<name>org.eclipse.jst.j2ee.ejb.annotations.xdoclet.xdocletbuilder</name>
|
||||||
|
<arguments>
|
||||||
|
</arguments>
|
||||||
|
</buildCommand>
|
||||||
|
</buildSpec>
|
||||||
|
<natures>
|
||||||
|
<nature>org.eclipse.wst.common.project.facet.core.nature</nature>
|
||||||
|
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||||
|
<nature>org.eclipse.wst.common.modulecore.ModuleCoreNature</nature>
|
||||||
|
<nature>org.eclipse.jem.workbench.JavaEMFNature</nature>
|
||||||
|
</natures>
|
||||||
|
</projectDescription>
|
9
auth_token/server/CasaAuthServer/.settings/.component
Normal file
9
auth_token/server/CasaAuthServer/.settings/.component
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project-modules id="moduleCoreId">
|
||||||
|
<wb-module deploy-name="CasaAuthServer">
|
||||||
|
<wb-resource source-path="/WebContent" deploy-path="/"/>
|
||||||
|
<property name="context-root" value="CasaAuthServer"/>
|
||||||
|
<property name="java-output-path" value="/build/classes/"/>
|
||||||
|
</wb-module>
|
||||||
|
</project-modules>
|
||||||
|
|
12
auth_token/server/CasaAuthServer/.settings/.component-bad
Normal file
12
auth_token/server/CasaAuthServer/.settings/.component-bad
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project-modules id="moduleCoreId">
|
||||||
|
<wb-module deploy-name="CasaAuthServer">
|
||||||
|
<wb-resource source-path="/WebContent" deploy-path="/"/>
|
||||||
|
<wb-resource source-path="/build/classes" deploy-path="/WEB-INF/classes"/>
|
||||||
|
<wb-resource source-path="/com.novell.casa.jaas" deploy-path="/WEB-INF/classes"/>
|
||||||
|
<wb-resource source-path="/src.com.novell.casa.jaas" deploy-path="/WEB-INF/classes"/>
|
||||||
|
<property name="context-root" value="CasaAuthServer"/>
|
||||||
|
<property name="java-output-path" value="/build/classes/"/>
|
||||||
|
</wb-module>
|
||||||
|
</project-modules>
|
||||||
|
|
10
auth_token/server/CasaAuthServer/.settings/.component-save
Normal file
10
auth_token/server/CasaAuthServer/.settings/.component-save
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project-modules id="moduleCoreId">
|
||||||
|
<wb-module deploy-name="CasaAuthServer">
|
||||||
|
<wb-resource source-path="/WebContent" deploy-path="/"/>
|
||||||
|
<wb-resource source-path="/build/classes" deploy-path="/WEB-INF/classes"/>
|
||||||
|
<property name="context-root" value="CasaAuthServer"/>
|
||||||
|
<property name="java-output-path" value="/build/classes/"/>
|
||||||
|
</wb-module>
|
||||||
|
</project-modules>
|
||||||
|
|
@ -0,0 +1,249 @@
|
|||||||
|
#Tue Mar 21 11:49:00 MST 2006
|
||||||
|
eclipse.preferences.version=1
|
||||||
|
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
||||||
|
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.2
|
||||||
|
org.eclipse.jdt.core.compiler.compliance=1.4
|
||||||
|
org.eclipse.jdt.core.compiler.problem.assertIdentifier=warning
|
||||||
|
org.eclipse.jdt.core.compiler.problem.enumIdentifier=warning
|
||||||
|
org.eclipse.jdt.core.compiler.source=1.3
|
||||||
|
org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
|
||||||
|
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
|
||||||
|
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16
|
||||||
|
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16
|
||||||
|
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16
|
||||||
|
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16
|
||||||
|
org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16
|
||||||
|
org.eclipse.jdt.core.formatter.alignment_for_compact_if=16
|
||||||
|
org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80
|
||||||
|
org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0
|
||||||
|
org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16
|
||||||
|
org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16
|
||||||
|
org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
|
||||||
|
org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
|
||||||
|
org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16
|
||||||
|
org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16
|
||||||
|
org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16
|
||||||
|
org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16
|
||||||
|
org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16
|
||||||
|
org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16
|
||||||
|
org.eclipse.jdt.core.formatter.blank_lines_after_imports=1
|
||||||
|
org.eclipse.jdt.core.formatter.blank_lines_after_package=1
|
||||||
|
org.eclipse.jdt.core.formatter.blank_lines_before_field=1
|
||||||
|
org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0
|
||||||
|
org.eclipse.jdt.core.formatter.blank_lines_before_imports=1
|
||||||
|
org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1
|
||||||
|
org.eclipse.jdt.core.formatter.blank_lines_before_method=1
|
||||||
|
org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1
|
||||||
|
org.eclipse.jdt.core.formatter.blank_lines_before_package=0
|
||||||
|
org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1
|
||||||
|
org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line
|
||||||
|
org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line
|
||||||
|
org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line
|
||||||
|
org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line
|
||||||
|
org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line
|
||||||
|
org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line
|
||||||
|
org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line
|
||||||
|
org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line
|
||||||
|
org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line
|
||||||
|
org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line
|
||||||
|
org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line
|
||||||
|
org.eclipse.jdt.core.formatter.comment.clear_blank_lines=false
|
||||||
|
org.eclipse.jdt.core.formatter.comment.format_comments=true
|
||||||
|
org.eclipse.jdt.core.formatter.comment.format_header=false
|
||||||
|
org.eclipse.jdt.core.formatter.comment.format_html=true
|
||||||
|
org.eclipse.jdt.core.formatter.comment.format_source_code=true
|
||||||
|
org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true
|
||||||
|
org.eclipse.jdt.core.formatter.comment.indent_root_tags=true
|
||||||
|
org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert
|
||||||
|
org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert
|
||||||
|
org.eclipse.jdt.core.formatter.comment.line_length=80
|
||||||
|
org.eclipse.jdt.core.formatter.compact_else_if=true
|
||||||
|
org.eclipse.jdt.core.formatter.continuation_indentation=2
|
||||||
|
org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2
|
||||||
|
org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false
|
||||||
|
org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true
|
||||||
|
org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true
|
||||||
|
org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true
|
||||||
|
org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true
|
||||||
|
org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true
|
||||||
|
org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true
|
||||||
|
org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true
|
||||||
|
org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false
|
||||||
|
org.eclipse.jdt.core.formatter.indentation.size=4
|
||||||
|
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false
|
||||||
|
org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false
|
||||||
|
org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false
|
||||||
|
org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false
|
||||||
|
org.eclipse.jdt.core.formatter.lineSplit=80
|
||||||
|
org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0
|
||||||
|
org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1
|
||||||
|
org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true
|
||||||
|
org.eclipse.jdt.core.formatter.tabulation.char=tab
|
||||||
|
org.eclipse.jdt.core.formatter.tabulation.size=4
|
||||||
|
org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false
|
@ -0,0 +1,4 @@
|
|||||||
|
#Tue Mar 21 11:44:16 MST 2006
|
||||||
|
eclipse.preferences.version=1
|
||||||
|
formatter_settings_version=8
|
||||||
|
internal.default.compliance=default
|
@ -0,0 +1,3 @@
|
|||||||
|
#Thu Mar 09 09:05:25 MST 2006
|
||||||
|
classpath.helper/org.eclipse.jdt.launching.JRE_CONTAINER\:\:org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType\:\:java-1.4.2-sun-1.4.2.10/owners=jst.java\:1.4
|
||||||
|
eclipse.preferences.version=1
|
@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<faceted-project>
|
||||||
|
<fixed facet="jst.web"/>
|
||||||
|
<fixed facet="jst.java"/>
|
||||||
|
<installed facet="jst.java" version="1.4"/>
|
||||||
|
<installed facet="jst.web" version="2.4"/>
|
||||||
|
</faceted-project>
|
@ -0,0 +1,3 @@
|
|||||||
|
Manifest-Version: 1.0
|
||||||
|
Class-Path:
|
||||||
|
|
65
auth_token/server/CasaAuthServer/WebContent/WEB-INF/web.xml
Normal file
65
auth_token/server/CasaAuthServer/WebContent/WEB-INF/web.xml
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<web-app id="WebApp_ID" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
|
||||||
|
<display-name>
|
||||||
|
CasaAuthServer</display-name>
|
||||||
|
<servlet>
|
||||||
|
<description>
|
||||||
|
</description>
|
||||||
|
<display-name>
|
||||||
|
GetAuthPolicy</display-name>
|
||||||
|
<servlet-name>GetAuthPolicy</servlet-name>
|
||||||
|
<servlet-class>
|
||||||
|
com.novell.casa.authserver.GetAuthPolicy</servlet-class>
|
||||||
|
</servlet>
|
||||||
|
<servlet>
|
||||||
|
<description>
|
||||||
|
</description>
|
||||||
|
<display-name>
|
||||||
|
PwdAuthenticate</display-name>
|
||||||
|
<servlet-name>PwdAuthenticate</servlet-name>
|
||||||
|
<servlet-class>
|
||||||
|
com.novell.casa.authserver.PwdAuthenticate</servlet-class>
|
||||||
|
</servlet>
|
||||||
|
<servlet>
|
||||||
|
<description>
|
||||||
|
</description>
|
||||||
|
<display-name>
|
||||||
|
Krb5Authenticate</display-name>
|
||||||
|
<servlet-name>Krb5Authenticate</servlet-name>
|
||||||
|
<servlet-class>
|
||||||
|
com.novell.casa.authserver.Krb5Authenticate</servlet-class>
|
||||||
|
</servlet>
|
||||||
|
<servlet>
|
||||||
|
<description>
|
||||||
|
</description>
|
||||||
|
<display-name>
|
||||||
|
GetAuthToken</display-name>
|
||||||
|
<servlet-name>GetAuthToken</servlet-name>
|
||||||
|
<servlet-class>
|
||||||
|
com.novell.casa.authserver.GetAuthToken</servlet-class>
|
||||||
|
</servlet>
|
||||||
|
<servlet-mapping>
|
||||||
|
<servlet-name>GetAuthPolicy</servlet-name>
|
||||||
|
<url-pattern>/GetAuthPolicy</url-pattern>
|
||||||
|
</servlet-mapping>
|
||||||
|
<servlet-mapping>
|
||||||
|
<servlet-name>PwdAuthenticate</servlet-name>
|
||||||
|
<url-pattern>/PwdAuthenticate</url-pattern>
|
||||||
|
</servlet-mapping>
|
||||||
|
<servlet-mapping>
|
||||||
|
<servlet-name>Krb5Authenticate</servlet-name>
|
||||||
|
<url-pattern>/Krb5Authenticate</url-pattern>
|
||||||
|
</servlet-mapping>
|
||||||
|
<servlet-mapping>
|
||||||
|
<servlet-name>GetAuthToken</servlet-name>
|
||||||
|
<url-pattern>/GetAuthToken</url-pattern>
|
||||||
|
</servlet-mapping>
|
||||||
|
<welcome-file-list>
|
||||||
|
<welcome-file>index.html</welcome-file>
|
||||||
|
<welcome-file>index.htm</welcome-file>
|
||||||
|
<welcome-file>index.jsp</welcome-file>
|
||||||
|
<welcome-file>default.html</welcome-file>
|
||||||
|
<welcome-file>default.htm</welcome-file>
|
||||||
|
<welcome-file>default.jsp</welcome-file>
|
||||||
|
</welcome-file-list>
|
||||||
|
</web-app>
|
@ -0,0 +1,278 @@
|
|||||||
|
/***********************************************************************
|
||||||
|
*
|
||||||
|
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; version 2.1
|
||||||
|
* of the License.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Library Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, Novell, Inc.
|
||||||
|
*
|
||||||
|
* To contact Novell about this file by physical or electronic mail,
|
||||||
|
* you may find current contact information at www.novell.com.
|
||||||
|
*
|
||||||
|
* Author: Juan Carlos Luciani <jluciani@novell.com>
|
||||||
|
*
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
package com.novell.casa.authserver;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
|
||||||
|
import org.xml.sax.InputSource;
|
||||||
|
import org.xml.sax.SAXException;
|
||||||
|
import org.xml.sax.XMLReader;
|
||||||
|
import org.xml.sax.helpers.XMLReaderFactory;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* AuthReqMsg Class.
|
||||||
|
*
|
||||||
|
* This class deals with the message sent by Casa Client when requesting
|
||||||
|
* that an entity be authenticated. The format of the message is as
|
||||||
|
* follows:
|
||||||
|
*
|
||||||
|
* <?xml version="1.0" encoding="ISO-8859-1"?>
|
||||||
|
* <auth_req>
|
||||||
|
* <realm>realm value</realm>
|
||||||
|
* <auth_mech_token>mechanism token data</auth_mech_token>
|
||||||
|
* </auth_req>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class AuthReqMsg {
|
||||||
|
|
||||||
|
protected String m_realm = null;
|
||||||
|
protected String m_authMechToken = null;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Class for handling Authentication Request parsing events.
|
||||||
|
*/
|
||||||
|
private class SAXHandler extends org.xml.sax.helpers.DefaultHandler
|
||||||
|
{
|
||||||
|
private final static int AWAITING_ROOT_ELEMENT_START = 0;
|
||||||
|
private final static int AWAITING_ROOT_ELEMENT_END = 1;
|
||||||
|
private final static int AWAITING_REALM_ELEMENT_START = 2;
|
||||||
|
private final static int AWAITING_REALM_ELEMENT_END = 3;
|
||||||
|
private final static int AWAITING_REALM_DATA = 4;
|
||||||
|
private final static int AWAITING_AUTH_MECH_TOKEN_ELEMENT_START = 5;
|
||||||
|
private final static int AWAITING_AUTH_MECH_TOKEN_ELEMENT_END = 6;
|
||||||
|
private final static int AWAITING_AUTH_MECH_TOKEN_DATA = 7;
|
||||||
|
private final static int DONE_PARSING = 8;
|
||||||
|
|
||||||
|
private AuthReqMsg m_authReqMsg;
|
||||||
|
private int m_state;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Constructor
|
||||||
|
*/
|
||||||
|
public SAXHandler (AuthReqMsg authReqMsg)
|
||||||
|
{
|
||||||
|
super();
|
||||||
|
|
||||||
|
// Initialize our members
|
||||||
|
m_authReqMsg = authReqMsg;
|
||||||
|
m_state = AWAITING_ROOT_ELEMENT_START;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* endDocument() implementation.
|
||||||
|
*/
|
||||||
|
public void endDocument () throws SAXException
|
||||||
|
{
|
||||||
|
// Verify that we obtained all of the required elements
|
||||||
|
if (m_state != DONE_PARSING)
|
||||||
|
{
|
||||||
|
System.err.println("AuthReqMsg SAXHandler.endDocument()- Missing element");
|
||||||
|
throw new SAXException("Missing element");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* startElement() implementation.
|
||||||
|
*/
|
||||||
|
public void startElement (String uri, String name, String qName, org.xml.sax.Attributes atts) throws SAXException
|
||||||
|
{
|
||||||
|
// Proceed based on our state
|
||||||
|
switch (m_state) {
|
||||||
|
|
||||||
|
case AWAITING_ROOT_ELEMENT_START:
|
||||||
|
// Verify that we are processing the expected tag
|
||||||
|
if (ProtoDefs.authRequestElementName.equals(qName))
|
||||||
|
{
|
||||||
|
// Advance to the next state
|
||||||
|
m_state = AWAITING_REALM_ELEMENT_START;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
System.err.println("AuthReqMsg SAXHandler.startElement()- Un-expected element");
|
||||||
|
throw new SAXException("Un-expected element");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AWAITING_REALM_ELEMENT_START:
|
||||||
|
// Verify that we are processing the expected tag
|
||||||
|
if (ProtoDefs.realmElementName.equals(qName))
|
||||||
|
{
|
||||||
|
// Advance to the next state
|
||||||
|
m_state = AWAITING_REALM_DATA;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
System.err.println("AuthReqMsg SAXHandler.startElement()- Un-expected element");
|
||||||
|
throw new SAXException("Un-expected element");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AWAITING_AUTH_MECH_TOKEN_ELEMENT_START:
|
||||||
|
// Verify that we are processing the expected tag
|
||||||
|
if (ProtoDefs.authMechTokenElementName.equals(qName))
|
||||||
|
{
|
||||||
|
// Advance to the next state
|
||||||
|
m_state = AWAITING_AUTH_MECH_TOKEN_DATA;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
System.err.println("AuthReqMsg SAXHandler.startElement()- Un-expected element");
|
||||||
|
throw new SAXException("Un-expected element");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
System.err.println("AuthReqMsg SAXHandler.startElement()- State error");
|
||||||
|
throw new SAXException("State error");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* endElement() immplementation.
|
||||||
|
*/
|
||||||
|
public void endElement (String uri, String name, String qName) throws SAXException
|
||||||
|
{
|
||||||
|
// Proceed based on our state
|
||||||
|
switch (m_state) {
|
||||||
|
|
||||||
|
case AWAITING_ROOT_ELEMENT_END:
|
||||||
|
// Verify that we are processing the expected tag
|
||||||
|
if (ProtoDefs.authRequestElementName.equals(qName))
|
||||||
|
{
|
||||||
|
// Advance to the next state
|
||||||
|
m_state = DONE_PARSING;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
System.err.println("AuthReqMsg SAXHandler.endElement()- Un-expected element");
|
||||||
|
throw new SAXException("Un-expected element");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AWAITING_REALM_ELEMENT_END:
|
||||||
|
// Verify that we are processing the expected tag
|
||||||
|
if (ProtoDefs.realmElementName.equals(qName))
|
||||||
|
{
|
||||||
|
// Advance to the next state
|
||||||
|
m_state = AWAITING_AUTH_MECH_TOKEN_ELEMENT_START;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
System.err.println("AuthReqMsg SAXHandler.endElement()- Un-expected element");
|
||||||
|
throw new SAXException("Un-expected element");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AWAITING_AUTH_MECH_TOKEN_ELEMENT_END:
|
||||||
|
// Verify that we are processing the expected tag
|
||||||
|
if (ProtoDefs.authMechTokenElementName.equals(qName))
|
||||||
|
{
|
||||||
|
// Advance to the next state
|
||||||
|
m_state = AWAITING_ROOT_ELEMENT_END;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
System.err.println("AuthReqMsg SAXHandler.endElement()- Un-expected element");
|
||||||
|
throw new SAXException("Un-expected element");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
System.err.println("AuthReqMsg SAXHandler.startElement()- State error");
|
||||||
|
throw new SAXException("State error");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* character() implementation.
|
||||||
|
*/
|
||||||
|
public void characters (char ch[], int start, int length) throws SAXException
|
||||||
|
{
|
||||||
|
// Proceed based on our state
|
||||||
|
switch (m_state) {
|
||||||
|
|
||||||
|
case AWAITING_REALM_DATA:
|
||||||
|
// Consume the data
|
||||||
|
m_authReqMsg.m_realm = new String(ch, start, length);
|
||||||
|
|
||||||
|
// Advance to the next state
|
||||||
|
m_state = AWAITING_REALM_ELEMENT_END;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AWAITING_AUTH_MECH_TOKEN_DATA:
|
||||||
|
// Consume the data
|
||||||
|
m_authReqMsg.m_authMechToken = new String(ch, start, length);
|
||||||
|
|
||||||
|
// Advance to the next state
|
||||||
|
m_state = AWAITING_AUTH_MECH_TOKEN_ELEMENT_END;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
// Do nothing
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Constructor
|
||||||
|
*/
|
||||||
|
public AuthReqMsg (InputStream inStream) throws Exception
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Parse the AuthReqMsg
|
||||||
|
XMLReader xr = XMLReaderFactory.createXMLReader();
|
||||||
|
SAXHandler handler = new SAXHandler(this);
|
||||||
|
xr.setContentHandler(handler);
|
||||||
|
xr.setErrorHandler(handler);
|
||||||
|
|
||||||
|
InputSource source = new InputSource(inStream);
|
||||||
|
xr.parse(source);
|
||||||
|
}
|
||||||
|
catch (SAXException e)
|
||||||
|
{
|
||||||
|
System.err.println("AuthReqMsg()- Parse exception: " + e.toString());
|
||||||
|
throw new Exception("Protocol error");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Method to get the authentication realm.
|
||||||
|
*/
|
||||||
|
public String getRealm() throws Exception
|
||||||
|
{
|
||||||
|
return m_realm;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Method to get the authentication mechanism token.
|
||||||
|
*/
|
||||||
|
public String getAuthMechToken() throws Exception
|
||||||
|
{
|
||||||
|
return m_authMechToken;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,112 @@
|
|||||||
|
/***********************************************************************
|
||||||
|
*
|
||||||
|
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; version 2.1
|
||||||
|
* of the License.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Library Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, Novell, Inc.
|
||||||
|
*
|
||||||
|
* To contact Novell about this file by physical or electronic mail,
|
||||||
|
* you may find current contact information at www.novell.com.
|
||||||
|
*
|
||||||
|
* Author: Juan Carlos Luciani <jluciani@novell.com>
|
||||||
|
*
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
package com.novell.casa.authserver;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* AuthRespMsg Class.
|
||||||
|
*
|
||||||
|
* This class deals with the message sent to the CASA Client as a
|
||||||
|
* response to an authentication request. The format of the message is
|
||||||
|
* as follows when the response includes a session token:
|
||||||
|
*
|
||||||
|
* <?xml version="1.0" encoding="ISO-8859-1"?>
|
||||||
|
* <auth_resp>
|
||||||
|
* <status><description>OK</description>200</status>
|
||||||
|
* <session_token><lifetime>lifetime value</lifetime>session token data</session_token>
|
||||||
|
* </auth_resp>
|
||||||
|
*
|
||||||
|
* The format of the message is as follows when the response does not
|
||||||
|
* include a session token.
|
||||||
|
*
|
||||||
|
* <?xml version="1.0" encoding="ISO-8859-1"?>
|
||||||
|
* <auth_resp>
|
||||||
|
* <status><description>status description</description>status code</status>
|
||||||
|
* </auth_resp>
|
||||||
|
*
|
||||||
|
* Plase note that the protocol utilizes the status codes defined
|
||||||
|
* in the HTTP 1.1 Specification.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class AuthRespMsg {
|
||||||
|
|
||||||
|
String m_msg;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Constructor for a msg that does not include the session token.
|
||||||
|
*/
|
||||||
|
public AuthRespMsg (
|
||||||
|
String statusDescription,
|
||||||
|
String statusCode) throws Exception
|
||||||
|
{
|
||||||
|
// Get a StringBuffer to help us with the construction of the message
|
||||||
|
StringBuffer sb = new StringBuffer();
|
||||||
|
|
||||||
|
// Start building the message
|
||||||
|
sb.append(ProtoDefs.xmlDeclaration + "\r\n");
|
||||||
|
sb.append("<" + ProtoDefs.authResponseElementName + ">" + "\r\n");
|
||||||
|
sb.append("<" + ProtoDefs.statusElementName + ">"
|
||||||
|
+ "<" + ProtoDefs.descriptionElementName + ">" + statusDescription + "</" + ProtoDefs.descriptionElementName + ">"
|
||||||
|
+ statusCode + "</" + ProtoDefs.statusElementName + ">" + "\r\n");
|
||||||
|
sb.append("</" + ProtoDefs.authResponseElementName + ">" + "\r\n");
|
||||||
|
|
||||||
|
// The message has now been built, save it.
|
||||||
|
m_msg = sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Constructor for a msg that includes the session token.
|
||||||
|
*/
|
||||||
|
public AuthRespMsg (
|
||||||
|
String statusDescription,
|
||||||
|
String statusCode,
|
||||||
|
String sessionToken,
|
||||||
|
String sessionTokenLifetime) throws Exception
|
||||||
|
{
|
||||||
|
// Get a StringBuffer to help us with the construction of the message
|
||||||
|
StringBuffer sb = new StringBuffer();
|
||||||
|
|
||||||
|
// Start building the message
|
||||||
|
sb.append(ProtoDefs.xmlDeclaration + "\r\n");
|
||||||
|
sb.append("<" + ProtoDefs.authResponseElementName + ">" + "\r\n");
|
||||||
|
sb.append("<" + ProtoDefs.statusElementName + ">"
|
||||||
|
+ "<" + ProtoDefs.descriptionElementName + ">" + ProtoDefs.httpOkStatusMsg + "</" + ProtoDefs.descriptionElementName + ">"
|
||||||
|
+ ProtoDefs.httpOkStatusCode + "</" + ProtoDefs.statusElementName + ">" + "\r\n");
|
||||||
|
sb.append("<" + ProtoDefs.sessionTokenElementName + ">"
|
||||||
|
+ "<" + ProtoDefs.lifetimeElementName + ">" + sessionTokenLifetime + "</" + ProtoDefs.lifetimeElementName + ">"
|
||||||
|
+ sessionToken + "</" + ProtoDefs.sessionTokenElementName + ">" + "\r\n");
|
||||||
|
sb.append("</" + ProtoDefs.authResponseElementName + ">" + "\r\n");
|
||||||
|
|
||||||
|
// The message has now been built, save it.
|
||||||
|
m_msg = sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns a string containing the AuthRespMsg.
|
||||||
|
*/
|
||||||
|
public String toString()
|
||||||
|
{
|
||||||
|
return m_msg;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,451 @@
|
|||||||
|
/***********************************************************************
|
||||||
|
*
|
||||||
|
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; version 2.1
|
||||||
|
* of the License.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Library Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, Novell, Inc.
|
||||||
|
*
|
||||||
|
* To contact Novell about this file by physical or electronic mail,
|
||||||
|
* you may find current contact information at www.novell.com.
|
||||||
|
*
|
||||||
|
* Author: Juan Carlos Luciani <jluciani@novell.com>
|
||||||
|
*
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
package com.novell.casa.authserver;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
|
||||||
|
import org.xml.sax.InputSource;
|
||||||
|
import org.xml.sax.SAXException;
|
||||||
|
import org.xml.sax.XMLReader;
|
||||||
|
import org.xml.sax.helpers.XMLReaderFactory;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* AuthToken Class.
|
||||||
|
*
|
||||||
|
* This class constructs authentication tokens that clients can present
|
||||||
|
* to services for authentication. The format of the authentication token
|
||||||
|
* is as follows:
|
||||||
|
*
|
||||||
|
* <?xml version="1.0" encoding="ISO-8859-1"?>
|
||||||
|
* <auth_token>
|
||||||
|
* <signature>signature value</signature>
|
||||||
|
* <lifetime>lifetime value</lifetime>
|
||||||
|
* <ident_token><type>Identity Token type</type>identity token data</ident_token>
|
||||||
|
* </auth_token>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class AuthToken {
|
||||||
|
|
||||||
|
private String m_token;
|
||||||
|
private String m_lifetime;
|
||||||
|
private String m_identityTokenType;
|
||||||
|
private StringBuffer m_identityToken;
|
||||||
|
private String m_signature;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Class for handling parsing events.
|
||||||
|
*/
|
||||||
|
private class SAXHandler extends org.xml.sax.helpers.DefaultHandler
|
||||||
|
{
|
||||||
|
private final static int AWAITING_ROOT_ELEMENT_START = 0;
|
||||||
|
private final static int AWAITING_ROOT_ELEMENT_END = 1;
|
||||||
|
private final static int AWAITING_SIGNATURE_ELEMENT_START = 2;
|
||||||
|
private final static int AWAITING_SIGNATURE_ELEMENT_END = 3;
|
||||||
|
private final static int AWAITING_SIGNATURE_DATA = 4;
|
||||||
|
private final static int AWAITING_LIFETIME_ELEMENT_START = 5;
|
||||||
|
private final static int AWAITING_LIFETIME_ELEMENT_END = 6;
|
||||||
|
private final static int AWAITING_LIFETIME_DATA = 7;
|
||||||
|
private final static int AWAITING_IDENT_TOKEN_ELEMENT_START = 8;
|
||||||
|
private final static int AWAITING_IDENT_TOKEN_ELEMENT_END = 9;
|
||||||
|
private final static int AWAITING_IDENT_TOKEN_DATA = 10;
|
||||||
|
private final static int AWAITING_TYPE_ELEMENT_START = 11;
|
||||||
|
private final static int AWAITING_TYPE_ELEMENT_END = 12;
|
||||||
|
private final static int AWAITING_TYPE_DATA = 13;
|
||||||
|
private final static int DONE_PARSING = 14;
|
||||||
|
|
||||||
|
private AuthToken m_AuthToken;
|
||||||
|
private int m_state;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Constructor
|
||||||
|
*/
|
||||||
|
public SAXHandler (AuthToken AuthToken)
|
||||||
|
{
|
||||||
|
super();
|
||||||
|
|
||||||
|
// Initialize our members
|
||||||
|
m_AuthToken = AuthToken;
|
||||||
|
m_state = AWAITING_ROOT_ELEMENT_START;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* endDocument() implementation.
|
||||||
|
*/
|
||||||
|
public void endDocument () throws SAXException
|
||||||
|
{
|
||||||
|
// Verify that we obtained all of the required elements
|
||||||
|
if (m_state != DONE_PARSING)
|
||||||
|
{
|
||||||
|
System.err.println("AuthToken SAXHandler.endDocument()- Missing element");
|
||||||
|
throw new SAXException("Missing element");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* startElement() implementation.
|
||||||
|
*/
|
||||||
|
public void startElement (String uri, String name, String qName, org.xml.sax.Attributes atts) throws SAXException
|
||||||
|
{
|
||||||
|
// Proceed based on our state
|
||||||
|
switch (m_state) {
|
||||||
|
|
||||||
|
case AWAITING_ROOT_ELEMENT_START:
|
||||||
|
// Verify that we are processing the expected tag
|
||||||
|
if (ProtoDefs.authTokenElementName.equals(qName))
|
||||||
|
{
|
||||||
|
// Advance to the next state
|
||||||
|
m_state = AWAITING_SIGNATURE_ELEMENT_START;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
System.err.println("AuthToken SAXHandler.startElement()- Un-expected element");
|
||||||
|
throw new SAXException("Un-expected element");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AWAITING_SIGNATURE_ELEMENT_START:
|
||||||
|
// Verify that we are processing the expected tag
|
||||||
|
if (ProtoDefs.signatureElementName.equals(qName))
|
||||||
|
{
|
||||||
|
// Advance to the next state
|
||||||
|
m_state = AWAITING_SIGNATURE_DATA;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
System.err.println("AuthToken SAXHandler.startElement()- Un-expected element");
|
||||||
|
throw new SAXException("Un-expected element");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AWAITING_LIFETIME_ELEMENT_START:
|
||||||
|
// Verify that we are processing the expected tag
|
||||||
|
if (ProtoDefs.lifetimeElementName.equals(qName))
|
||||||
|
{
|
||||||
|
// Advance to the next state
|
||||||
|
m_state = AWAITING_LIFETIME_DATA;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
System.err.println("AuthToken SAXHandler.startElement()- Un-expected element");
|
||||||
|
throw new SAXException("Un-expected element");
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AWAITING_IDENT_TOKEN_ELEMENT_START:
|
||||||
|
// Verify that we are processing the expected tag
|
||||||
|
if (ProtoDefs.identTokenElementName.equals(qName))
|
||||||
|
{
|
||||||
|
// Advance to the next state
|
||||||
|
m_state = AWAITING_TYPE_ELEMENT_START;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
System.err.println("AuthToken SAXHandler.startElement()- Un-expected element");
|
||||||
|
throw new SAXException("Un-expected element");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AWAITING_TYPE_ELEMENT_START:
|
||||||
|
// Verify that we are processing the expected tag
|
||||||
|
if (ProtoDefs.typeElementName.equals(qName))
|
||||||
|
{
|
||||||
|
// Advance to the next state
|
||||||
|
m_state = AWAITING_TYPE_DATA;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
System.err.println("AuthToken SAXHandler.startElement()- Un-expected element");
|
||||||
|
throw new SAXException("Un-expected element");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
System.err.println("AuthToken SAXHandler.startElement()- State error");
|
||||||
|
throw new SAXException("State error");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* endElement() immplementation.
|
||||||
|
*/
|
||||||
|
public void endElement (String uri, String name, String qName) throws SAXException
|
||||||
|
{
|
||||||
|
// Proceed based on our state
|
||||||
|
switch (m_state) {
|
||||||
|
|
||||||
|
case AWAITING_ROOT_ELEMENT_END:
|
||||||
|
// Verify that we are processing the expected tag
|
||||||
|
if (ProtoDefs.authTokenElementName.equals(qName))
|
||||||
|
{
|
||||||
|
// Advance to the next state
|
||||||
|
m_state = DONE_PARSING;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
System.err.println("AuthToken SAXHandler.endElement()- Un-expected element");
|
||||||
|
throw new SAXException("Un-expected element");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AWAITING_SIGNATURE_ELEMENT_END:
|
||||||
|
// Verify that we are processing the expected tag
|
||||||
|
if (ProtoDefs.signatureElementName.equals(qName))
|
||||||
|
{
|
||||||
|
// Advance to the next state
|
||||||
|
m_state = AWAITING_LIFETIME_ELEMENT_START;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
System.err.println("AuthToken SAXHandler.endElement()- Un-expected element");
|
||||||
|
throw new SAXException("Un-expected element");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AWAITING_LIFETIME_ELEMENT_END:
|
||||||
|
// Verify that we are processing the expected tag
|
||||||
|
if (ProtoDefs.lifetimeElementName.equals(qName))
|
||||||
|
{
|
||||||
|
// Advance to the next state
|
||||||
|
m_state = AWAITING_IDENT_TOKEN_ELEMENT_START;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
System.err.println("AuthToken SAXHandler.endElement()- Un-expected element");
|
||||||
|
throw new SAXException("Un-expected element");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AWAITING_TYPE_ELEMENT_END:
|
||||||
|
// Verify that we are processing the expected tag
|
||||||
|
if (ProtoDefs.typeElementName.equals(qName))
|
||||||
|
{
|
||||||
|
// Advance to the next state
|
||||||
|
m_state = AWAITING_IDENT_TOKEN_DATA;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
System.err.println("AuthToken SAXHandler.endElement()- Un-expected element");
|
||||||
|
throw new SAXException("Un-expected element");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AWAITING_IDENT_TOKEN_ELEMENT_END:
|
||||||
|
// Verify that we are processing the expected tag
|
||||||
|
if (ProtoDefs.identTokenElementName.equals(qName))
|
||||||
|
{
|
||||||
|
// Advance to the next state
|
||||||
|
m_state = AWAITING_ROOT_ELEMENT_END;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
System.err.println("AuthToken SAXHandler.endElement()- Un-expected element");
|
||||||
|
throw new SAXException("Un-expected element");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
System.err.println("AuthToken SAXHandler.startElement()- State error");
|
||||||
|
throw new SAXException("State error");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* character() implementation.
|
||||||
|
*/
|
||||||
|
public void characters (char ch[], int start, int length) throws SAXException
|
||||||
|
{
|
||||||
|
// Proceed based on our state
|
||||||
|
switch (m_state) {
|
||||||
|
|
||||||
|
case AWAITING_SIGNATURE_DATA:
|
||||||
|
// Consume the data
|
||||||
|
m_AuthToken.m_signature = new String(ch, start, length);
|
||||||
|
|
||||||
|
// Advance to the next state
|
||||||
|
m_state = AWAITING_SIGNATURE_ELEMENT_END;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AWAITING_LIFETIME_DATA:
|
||||||
|
// Consume the data
|
||||||
|
m_AuthToken.m_lifetime = new String(ch, start, length);
|
||||||
|
|
||||||
|
// Advance to the next state
|
||||||
|
m_state = AWAITING_LIFETIME_ELEMENT_END;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AWAITING_TYPE_DATA:
|
||||||
|
// Consume the data
|
||||||
|
m_AuthToken.m_identityTokenType = new String(ch, start, length);
|
||||||
|
|
||||||
|
// Advance to the next state
|
||||||
|
m_state = AWAITING_TYPE_ELEMENT_END;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AWAITING_IDENT_TOKEN_DATA:
|
||||||
|
case AWAITING_IDENT_TOKEN_ELEMENT_END:
|
||||||
|
// Consume the data
|
||||||
|
m_AuthToken.m_identityToken.append(ch, start, length);
|
||||||
|
|
||||||
|
// Advance to the next state
|
||||||
|
m_state = AWAITING_IDENT_TOKEN_ELEMENT_END;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
// Do nothing
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Constructor.
|
||||||
|
*/
|
||||||
|
public AuthToken (
|
||||||
|
String identityId,
|
||||||
|
String realm,
|
||||||
|
String targetService,
|
||||||
|
String targetHost) throws Exception
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Verify that we have support for the specified service.
|
||||||
|
// tbd
|
||||||
|
|
||||||
|
// For now lets use the services of the only IdentityToken provider
|
||||||
|
// that we have.
|
||||||
|
//
|
||||||
|
// tbd - Add code to allow for the consumption of tokens
|
||||||
|
// from different providers.
|
||||||
|
CasaIdentityToken identityToken = new CasaIdentityToken();
|
||||||
|
identityToken.initialize(identityId,
|
||||||
|
realm,
|
||||||
|
targetService,
|
||||||
|
targetHost);
|
||||||
|
|
||||||
|
m_identityToken = new StringBuffer();
|
||||||
|
m_identityToken.append(identityToken.getEncodedToken());
|
||||||
|
m_identityTokenType = identityToken.getProviderType();
|
||||||
|
|
||||||
|
m_lifetime = "tbd";
|
||||||
|
|
||||||
|
// Generate a signature
|
||||||
|
// tbd - Over identToken, identToken type, and lifetime data.
|
||||||
|
m_signature = "tbd";
|
||||||
|
|
||||||
|
// Get a StringBuffer to help us with the construction of the token
|
||||||
|
StringBuffer sb = new StringBuffer();
|
||||||
|
|
||||||
|
// Start building the message
|
||||||
|
sb.append(ProtoDefs.xmlDeclaration + "\r\n");
|
||||||
|
sb.append("<" + ProtoDefs.authTokenElementName + ">" + "\r\n");
|
||||||
|
sb.append("<" + ProtoDefs.signatureElementName + ">" + m_signature + "</" + ProtoDefs.signatureElementName + ">" + "\r\n");
|
||||||
|
sb.append("<" + ProtoDefs.lifetimeElementName + ">" + m_lifetime + "</" + ProtoDefs.lifetimeElementName + ">" + "\r\n");
|
||||||
|
sb.append("<" + ProtoDefs.identTokenElementName + " mode=\"escaped\">"
|
||||||
|
+ "<" + ProtoDefs.typeElementName + ">" + m_identityTokenType + "</" + ProtoDefs.typeElementName + ">"
|
||||||
|
+ "<![CDATA["+ m_identityToken + "]]>" + "</" + ProtoDefs.identTokenElementName + ">" + "\r\n");
|
||||||
|
sb.append("</" + ProtoDefs.authTokenElementName + ">" + "\r\n");
|
||||||
|
|
||||||
|
// Save the token
|
||||||
|
m_token = sb.toString();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
// tbd
|
||||||
|
System.err.println("AuthToken()- Exception: " + e.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Constructor given an authentication token string. The constructor
|
||||||
|
* validates the token as part of its processing.
|
||||||
|
*/
|
||||||
|
public AuthToken(String token) throws Exception
|
||||||
|
{
|
||||||
|
// Decode the token string
|
||||||
|
m_token = Base64Coder.decode(token);
|
||||||
|
|
||||||
|
// Instantiate string buffer for the identity token
|
||||||
|
m_identityToken = new StringBuffer();
|
||||||
|
|
||||||
|
// Now parse the token into its elements
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Parse the AuthToken
|
||||||
|
XMLReader xr = XMLReaderFactory.createXMLReader();
|
||||||
|
SAXHandler handler = new SAXHandler(this);
|
||||||
|
xr.setContentHandler(handler);
|
||||||
|
xr.setErrorHandler(handler);
|
||||||
|
|
||||||
|
ByteArrayInputStream inStream = new ByteArrayInputStream(m_token.getBytes());
|
||||||
|
InputSource source = new InputSource(inStream);
|
||||||
|
xr.parse(source);
|
||||||
|
|
||||||
|
// Verify the signature
|
||||||
|
// tbd
|
||||||
|
|
||||||
|
// Verify that the token has not expired
|
||||||
|
// tbd
|
||||||
|
}
|
||||||
|
catch (SAXException e)
|
||||||
|
{
|
||||||
|
System.err.println("AuthToken()- Parse exception: " + e.toString());
|
||||||
|
throw new Exception("Protocol error");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns a string containing the Base64 encode token.
|
||||||
|
*/
|
||||||
|
public String toString()
|
||||||
|
{
|
||||||
|
return Base64Coder.encode(m_token);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns the lifetime of the token.
|
||||||
|
*/
|
||||||
|
public String getLifetime()
|
||||||
|
{
|
||||||
|
// tbd
|
||||||
|
return "60";
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns the identity token.
|
||||||
|
*/
|
||||||
|
public String getIdentityToken()
|
||||||
|
{
|
||||||
|
return m_identityToken.toString();
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Returns the identity token provider type.
|
||||||
|
*/
|
||||||
|
public String getIdentityTokenProviderType()
|
||||||
|
{
|
||||||
|
return m_identityTokenType;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,121 @@
|
|||||||
|
/**************************************************************************
|
||||||
|
*
|
||||||
|
* A Base64 Encoder/Decoder.
|
||||||
|
*
|
||||||
|
* This class is used to encode and decode data in Base64 format
|
||||||
|
* as described in RFC 1521.
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* Copyright 2003: Christian d'Heureuse, Inventec Informatik AG, Switzerland.<br>
|
||||||
|
* License: This is "Open Source" software and released under the <a href="http://www.gnu.org/licenses/lgpl.html" target="_top">GNU/LGPL</a> license.
|
||||||
|
* It is provided "as is" without warranty of any kind. Please contact the author for other licensing arrangements.<br>
|
||||||
|
* Home page: <a href="http://www.source-code.biz" target="_top">www.source-code.biz</a><br>
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* Version history:<br>
|
||||||
|
* 2003-07-22 Christian d'Heureuse (chdh): Module created.<br>
|
||||||
|
* 2005-08-11 chdh: Lincense changed from GPL to LGPL.
|
||||||
|
*
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
package com.novell.casa.authserver;
|
||||||
|
|
||||||
|
public class Base64Coder {
|
||||||
|
|
||||||
|
// Mapping table from 6-bit nibbles to Base64 characters.
|
||||||
|
private static char[] map1 = new char[64];
|
||||||
|
static {
|
||||||
|
int i=0;
|
||||||
|
for (char c='A'; c<='Z'; c++) map1[i++] = c;
|
||||||
|
for (char c='a'; c<='z'; c++) map1[i++] = c;
|
||||||
|
for (char c='0'; c<='9'; c++) map1[i++] = c;
|
||||||
|
map1[i++] = '+'; map1[i++] = '/'; }
|
||||||
|
|
||||||
|
// Mapping table from Base64 characters to 6-bit nibbles.
|
||||||
|
private static byte[] map2 = new byte[128];
|
||||||
|
static {
|
||||||
|
for (int i=0; i<map2.length; i++) map2[i] = -1;
|
||||||
|
for (int i=0; i<64; i++) map2[map1[i]] = (byte)i; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encodes a string into Base64 format.
|
||||||
|
* No blanks or line breaks are inserted.
|
||||||
|
* @param s a String to be encoded.
|
||||||
|
* @return A String with the Base64 encoded data.
|
||||||
|
*/
|
||||||
|
public static String encode (String s) {
|
||||||
|
return new String(encode(s.getBytes())); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encodes a byte array into Base64 format.
|
||||||
|
* No blanks or line breaks are inserted.
|
||||||
|
* @param in an array containing the data bytes to be encoded.
|
||||||
|
* @return A character array with the Base64 encoded data.
|
||||||
|
*/
|
||||||
|
public static char[] encode (byte[] in) {
|
||||||
|
int iLen = in.length;
|
||||||
|
int oDataLen = (iLen*4+2)/3; // output length without padding
|
||||||
|
int oLen = ((iLen+2)/3)*4; // output length including padding
|
||||||
|
char[] out = new char[oLen];
|
||||||
|
int ip = 0;
|
||||||
|
int op = 0;
|
||||||
|
while (ip < iLen) {
|
||||||
|
int i0 = in[ip++] & 0xff;
|
||||||
|
int i1 = ip < iLen ? in[ip++] & 0xff : 0;
|
||||||
|
int i2 = ip < iLen ? in[ip++] & 0xff : 0;
|
||||||
|
int o0 = i0 >>> 2;
|
||||||
|
int o1 = ((i0 & 3) << 4) | (i1 >>> 4);
|
||||||
|
int o2 = ((i1 & 0xf) << 2) | (i2 >>> 6);
|
||||||
|
int o3 = i2 & 0x3F;
|
||||||
|
out[op++] = map1[o0];
|
||||||
|
out[op++] = map1[o1];
|
||||||
|
out[op] = op < oDataLen ? map1[o2] : '='; op++;
|
||||||
|
out[op] = op < oDataLen ? map1[o3] : '='; op++; }
|
||||||
|
return out; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decodes a Base64 string.
|
||||||
|
* @param s a Base64 String to be decoded.
|
||||||
|
* @return A String containing the decoded data.
|
||||||
|
* @throws IllegalArgumentException if the input is not valid Base64 encoded data.
|
||||||
|
*/
|
||||||
|
public static String decode (String s) {
|
||||||
|
return new String(decode(s.toCharArray())); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decodes Base64 data.
|
||||||
|
* No blanks or line breaks are allowed within the Base64 encoded data.
|
||||||
|
* @param in a character array containing the Base64 encoded data.
|
||||||
|
* @return An array containing the decoded data bytes.
|
||||||
|
* @throws IllegalArgumentException if the input is not valid Base64 encoded data.
|
||||||
|
*/
|
||||||
|
public static byte[] decode (char[] in) {
|
||||||
|
int iLen = in.length;
|
||||||
|
if (iLen%4 != 0) throw new IllegalArgumentException ("Length of Base64 encoded input string is not a multiple of 4.");
|
||||||
|
while (iLen > 0 && in[iLen-1] == '=') iLen--;
|
||||||
|
int oLen = (iLen*3) / 4;
|
||||||
|
byte[] out = new byte[oLen];
|
||||||
|
int ip = 0;
|
||||||
|
int op = 0;
|
||||||
|
while (ip < iLen) {
|
||||||
|
int i0 = in[ip++];
|
||||||
|
int i1 = in[ip++];
|
||||||
|
int i2 = ip < iLen ? in[ip++] : 'A';
|
||||||
|
int i3 = ip < iLen ? in[ip++] : 'A';
|
||||||
|
if (i0 > 127 || i1 > 127 || i2 > 127 || i3 > 127)
|
||||||
|
throw new IllegalArgumentException ("Illegal character in Base64 encoded data.");
|
||||||
|
int b0 = map2[i0];
|
||||||
|
int b1 = map2[i1];
|
||||||
|
int b2 = map2[i2];
|
||||||
|
int b3 = map2[i3];
|
||||||
|
if (b0 < 0 || b1 < 0 || b2 < 0 || b3 < 0)
|
||||||
|
throw new IllegalArgumentException ("Illegal character in Base64 encoded data.");
|
||||||
|
int o0 = ( b0 <<2) | (b1>>>4);
|
||||||
|
int o1 = ((b1 & 0xf)<<4) | (b2>>>2);
|
||||||
|
int o2 = ((b2 & 3)<<6) | b3;
|
||||||
|
out[op++] = (byte)o0;
|
||||||
|
if (op<oLen) out[op++] = (byte)o1;
|
||||||
|
if (op<oLen) out[op++] = (byte)o2; }
|
||||||
|
return out; }
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,744 @@
|
|||||||
|
/***********************************************************************
|
||||||
|
*
|
||||||
|
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; version 2.1
|
||||||
|
* of the License.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Library Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, Novell, Inc.
|
||||||
|
*
|
||||||
|
* To contact Novell about this file by physical or electronic mail,
|
||||||
|
* you may find current contact information at www.novell.com.
|
||||||
|
*
|
||||||
|
* Author: Juan Carlos Luciani <jluciani@novell.com>
|
||||||
|
*
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
package com.novell.casa.authserver;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Hashtable;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import javax.naming.Context;
|
||||||
|
import javax.naming.NamingEnumeration;
|
||||||
|
import javax.naming.NamingException;
|
||||||
|
import javax.naming.directory.Attributes;
|
||||||
|
import javax.naming.directory.DirContext;
|
||||||
|
import javax.naming.directory.InitialDirContext;
|
||||||
|
|
||||||
|
import org.xml.sax.InputSource;
|
||||||
|
import org.xml.sax.SAXException;
|
||||||
|
import org.xml.sax.XMLReader;
|
||||||
|
import org.xml.sax.helpers.XMLReaderFactory;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* CasaIdentityToken Class.
|
||||||
|
*
|
||||||
|
* This class constructs Casa Identity tokens.
|
||||||
|
*
|
||||||
|
* A Casa Identity Token is a simple XML Document
|
||||||
|
* with information about an identity in the form
|
||||||
|
* of:
|
||||||
|
*
|
||||||
|
* <?xml version="1.0" encoding="ISO-8859-1"?>
|
||||||
|
* <casa_ident_tok>
|
||||||
|
* <id>identity id</id>
|
||||||
|
* <source_name>identity data source name</source_name>
|
||||||
|
* <source_url>identity data source url</source_url>
|
||||||
|
* <target_service>target service name</target_service>
|
||||||
|
* <target_host>target host name</target_host>
|
||||||
|
* <attributes>
|
||||||
|
* <attribute name>attribute value</attribute name>
|
||||||
|
* <attribute2 name>attribute2 value</attribute name>
|
||||||
|
* ...
|
||||||
|
* </attributes>
|
||||||
|
* </casa_ident_tok>
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* attribute/values pairs. The attribute names
|
||||||
|
* being the XML elements of the documents.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class CasaIdentityToken implements IdentityToken
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* XML Element Name Constants for the documents exchanged between the
|
||||||
|
* Casa Client and the Casa Server.
|
||||||
|
*/
|
||||||
|
private final static String casaIdentTokElementName = "casa_ident_tok";
|
||||||
|
private final static String idElementName = "id";
|
||||||
|
private final static String sourceNameElementName = "source_name";
|
||||||
|
private final static String sourceUrlElementName = "source_url";
|
||||||
|
private final static String targetServiceElementName = "target_service";
|
||||||
|
private final static String targetHostElementName = "target_host";
|
||||||
|
private final static String attributesElementName = "attributes";
|
||||||
|
|
||||||
|
|
||||||
|
private String m_identityId = null;
|
||||||
|
private String m_sourceName = null;
|
||||||
|
private String m_sourceUrl = null;
|
||||||
|
private String m_service = null;
|
||||||
|
private String m_host = null;
|
||||||
|
private String m_token = null;
|
||||||
|
private javax.naming.directory.Attributes m_attributes = null;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Class for handling Authentication Request parsing events.
|
||||||
|
*/
|
||||||
|
private class SAXHandler extends org.xml.sax.helpers.DefaultHandler
|
||||||
|
{
|
||||||
|
private final static int AWAITING_ROOT_ELEMENT_START = 0;
|
||||||
|
private final static int AWAITING_ROOT_ELEMENT_END = 1;
|
||||||
|
private final static int AWAITING_ID_ELEMENT_START = 2;
|
||||||
|
private final static int AWAITING_ID_ELEMENT_END = 3;
|
||||||
|
private final static int AWAITING_ID_DATA = 4;
|
||||||
|
private final static int AWAITING_SOURCE_NAME_ELEMENT_START = 5;
|
||||||
|
private final static int AWAITING_SOURCE_NAME_ELEMENT_END = 6;
|
||||||
|
private final static int AWAITING_SOURCE_NAME_DATA = 7;
|
||||||
|
private final static int AWAITING_SOURCE_URL_ELEMENT_START = 8;
|
||||||
|
private final static int AWAITING_SOURCE_URL_ELEMENT_END = 9;
|
||||||
|
private final static int AWAITING_SOURCE_URL_DATA = 10;
|
||||||
|
private final static int AWAITING_TARGET_SERVICE_ELEMENT_START = 11;
|
||||||
|
private final static int AWAITING_TARGET_SERVICE_ELEMENT_END = 12;
|
||||||
|
private final static int AWAITING_TARGET_SERVICE_DATA = 13;
|
||||||
|
private final static int AWAITING_TARGET_HOST_ELEMENT_START = 14;
|
||||||
|
private final static int AWAITING_TARGET_HOST_ELEMENT_END = 15;
|
||||||
|
private final static int AWAITING_TARGET_HOST_DATA = 16;
|
||||||
|
private final static int AWAITING_ATTRIBUTES_ELEMENT_START = 17;
|
||||||
|
private final static int AWAITING_ATTRIBUTE_START = 18;
|
||||||
|
private final static int AWAITING_ATTRIBUTE_END = 19;
|
||||||
|
private final static int AWAITING_ATTRIBUTE_DATA = 20;
|
||||||
|
private final static int DONE_PARSING = 21;
|
||||||
|
|
||||||
|
private CasaIdentityToken m_casaIdentToken;
|
||||||
|
private int m_state;
|
||||||
|
private String m_currAttribute;
|
||||||
|
private boolean m_encryptedAttrs;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Constructor
|
||||||
|
*/
|
||||||
|
public SAXHandler (CasaIdentityToken casaIdentityToken)
|
||||||
|
{
|
||||||
|
super();
|
||||||
|
|
||||||
|
// Initialize our members
|
||||||
|
m_casaIdentToken = casaIdentityToken;
|
||||||
|
m_state = AWAITING_ROOT_ELEMENT_START;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* endDocument() implementation.
|
||||||
|
*/
|
||||||
|
public void endDocument () throws SAXException
|
||||||
|
{
|
||||||
|
// Verify that we obtained all of the required elements
|
||||||
|
if (m_state != DONE_PARSING)
|
||||||
|
{
|
||||||
|
System.err.println("CasaIdentityToken SAXHandler.endDocument()- Missing element");
|
||||||
|
throw new SAXException("Missing element");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* startElement() implementation.
|
||||||
|
*/
|
||||||
|
public void startElement (String uri, String name, String qName, org.xml.sax.Attributes atts) throws SAXException
|
||||||
|
{
|
||||||
|
// Proceed based on our state
|
||||||
|
switch (m_state) {
|
||||||
|
|
||||||
|
case AWAITING_ROOT_ELEMENT_START:
|
||||||
|
// Verify that we are processing the expected tag
|
||||||
|
if (casaIdentTokElementName.equals(qName))
|
||||||
|
{
|
||||||
|
// Advance to the next state
|
||||||
|
m_state = AWAITING_ID_ELEMENT_START;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
System.err.println("CasaIdentityToken SAXHandler.startElement()- Un-expected element");
|
||||||
|
throw new SAXException("Un-expected element");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AWAITING_ID_ELEMENT_START:
|
||||||
|
// Verify that we are processing the expected tag
|
||||||
|
if (idElementName.equals(qName))
|
||||||
|
{
|
||||||
|
// Advance to the next state
|
||||||
|
m_state = AWAITING_ID_DATA;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
System.err.println("CasaIdentityToken SAXHandler.startElement()- Un-expected element");
|
||||||
|
throw new SAXException("Un-expected element");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AWAITING_SOURCE_NAME_ELEMENT_START:
|
||||||
|
// Verify that we are processing the expected tag
|
||||||
|
if (sourceNameElementName.equals(qName))
|
||||||
|
{
|
||||||
|
// Advance to the next state
|
||||||
|
m_state = AWAITING_SOURCE_NAME_DATA;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
System.err.println("CasaIdentityToken SAXHandler.startElement()- Un-expected element");
|
||||||
|
throw new SAXException("Un-expected element");
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AWAITING_SOURCE_URL_ELEMENT_START:
|
||||||
|
// Verify that we are processing the expected tag
|
||||||
|
if (sourceUrlElementName.equals(qName))
|
||||||
|
{
|
||||||
|
// Advance to the next state
|
||||||
|
m_state = AWAITING_SOURCE_URL_DATA;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
System.err.println("CasaIdentityToken SAXHandler.startElement()- Un-expected element");
|
||||||
|
throw new SAXException("Un-expected element");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AWAITING_TARGET_SERVICE_ELEMENT_START:
|
||||||
|
// Verify that we are processing the expected tag
|
||||||
|
if (targetServiceElementName.equals(qName))
|
||||||
|
{
|
||||||
|
// Advance to the next state
|
||||||
|
m_state = AWAITING_TARGET_SERVICE_DATA;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
System.err.println("CasaIdentityToken SAXHandler.startElement()- Un-expected element");
|
||||||
|
throw new SAXException("Un-expected element");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AWAITING_TARGET_HOST_ELEMENT_START:
|
||||||
|
// Verify that we are processing the expected tag
|
||||||
|
if (targetHostElementName.equals(qName))
|
||||||
|
{
|
||||||
|
// Advance to the next state
|
||||||
|
m_state = AWAITING_TARGET_HOST_DATA;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
System.err.println("CasaIdentityToken SAXHandler.startElement()- Un-expected element");
|
||||||
|
throw new SAXException("Un-expected element");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AWAITING_ATTRIBUTES_ELEMENT_START:
|
||||||
|
// Verify that we are processing the expected tag
|
||||||
|
if (attributesElementName.equals(qName))
|
||||||
|
{
|
||||||
|
// Advance to the next state
|
||||||
|
m_state = AWAITING_ATTRIBUTE_START;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
System.err.println("CasaIdentityToken SAXHandler.startElement()- Un-expected element");
|
||||||
|
throw new SAXException("Un-expected element");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AWAITING_ATTRIBUTE_START:
|
||||||
|
// Save the element name as the current attribute
|
||||||
|
m_currAttribute = qName;
|
||||||
|
|
||||||
|
// Advance to the next state
|
||||||
|
m_state = AWAITING_ATTRIBUTE_DATA;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
System.err.println("CasaIdentityToken SAXHandler.startElement()- State error");
|
||||||
|
throw new SAXException("State error");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* endElement() immplementation.
|
||||||
|
*/
|
||||||
|
public void endElement (String uri, String name, String qName) throws SAXException
|
||||||
|
{
|
||||||
|
// Proceed based on our state
|
||||||
|
switch (m_state) {
|
||||||
|
|
||||||
|
case AWAITING_ROOT_ELEMENT_END:
|
||||||
|
// Verify that we are processing the expected tag
|
||||||
|
if (casaIdentTokElementName.equals(qName))
|
||||||
|
{
|
||||||
|
// Advance to the next state
|
||||||
|
m_state = DONE_PARSING;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
System.err.println("CasaIdentityToken SAXHandler.endElement()- Un-expected element");
|
||||||
|
throw new SAXException("Un-expected element");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AWAITING_ID_ELEMENT_END:
|
||||||
|
// Verify that we are processing the expected tag
|
||||||
|
if (idElementName.equals(qName))
|
||||||
|
{
|
||||||
|
// Advance to the next state
|
||||||
|
m_state = AWAITING_SOURCE_NAME_ELEMENT_START;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
System.err.println("CasaIdentityToken SAXHandler.endElement()- Un-expected element");
|
||||||
|
throw new SAXException("Un-expected element");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AWAITING_SOURCE_NAME_ELEMENT_END:
|
||||||
|
// Verify that we are processing the expected tag
|
||||||
|
if (sourceNameElementName.equals(qName))
|
||||||
|
{
|
||||||
|
// Advance to the next state
|
||||||
|
m_state = AWAITING_SOURCE_URL_ELEMENT_START;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
System.err.println("CasaIdentityToken SAXHandler.endElement()- Un-expected element");
|
||||||
|
throw new SAXException("Un-expected element");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AWAITING_SOURCE_URL_ELEMENT_END:
|
||||||
|
// Verify that we are processing the expected tag
|
||||||
|
if (sourceUrlElementName.equals(qName))
|
||||||
|
{
|
||||||
|
// Advance to the next state
|
||||||
|
m_state = AWAITING_TARGET_SERVICE_ELEMENT_START;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
System.err.println("CasaIdentityToken SAXHandler.endElement()- Un-expected element");
|
||||||
|
throw new SAXException("Un-expected element");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AWAITING_TARGET_SERVICE_ELEMENT_END:
|
||||||
|
// Verify that we are processing the expected tag
|
||||||
|
if (targetServiceElementName.equals(qName))
|
||||||
|
{
|
||||||
|
// Advance to the next state
|
||||||
|
m_state = AWAITING_TARGET_HOST_ELEMENT_START;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
System.err.println("CasaIdentityToken SAXHandler.endElement()- Un-expected element");
|
||||||
|
throw new SAXException("Un-expected element");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AWAITING_TARGET_HOST_ELEMENT_END:
|
||||||
|
// Verify that we are processing the expected tag
|
||||||
|
if (targetHostElementName.equals(qName))
|
||||||
|
{
|
||||||
|
// Advance to the next state
|
||||||
|
m_state = AWAITING_ATTRIBUTES_ELEMENT_START;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
System.err.println("CasaIdentityToken SAXHandler.endElement()- Un-expected element");
|
||||||
|
throw new SAXException("Un-expected element");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AWAITING_ATTRIBUTE_END:
|
||||||
|
// Advance to the next state
|
||||||
|
m_state = AWAITING_ATTRIBUTE_START;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AWAITING_ATTRIBUTE_START:
|
||||||
|
// Verify that we are processing the expected tag
|
||||||
|
if (attributesElementName.equals(qName))
|
||||||
|
{
|
||||||
|
// Advance to the next state
|
||||||
|
m_state = AWAITING_ROOT_ELEMENT_END;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
System.err.println("CasaIdentityToken SAXHandler.endElement()- Un-expected element");
|
||||||
|
throw new SAXException("Un-expected element");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
System.err.println("CasaIdentityToken SAXHandler.startElement()- State error");
|
||||||
|
throw new SAXException("State error");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* character() implementation.
|
||||||
|
*/
|
||||||
|
public void characters (char ch[], int start, int length) throws SAXException
|
||||||
|
{
|
||||||
|
// Proceed based on our state
|
||||||
|
switch (m_state) {
|
||||||
|
|
||||||
|
case AWAITING_ID_DATA:
|
||||||
|
// Consume the data
|
||||||
|
m_casaIdentToken.m_identityId = new String(ch, start, length);
|
||||||
|
|
||||||
|
// Advance to the next state
|
||||||
|
m_state = AWAITING_ID_ELEMENT_END;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AWAITING_SOURCE_NAME_DATA:
|
||||||
|
// Consume the data
|
||||||
|
m_casaIdentToken.m_sourceName = new String(ch, start, length);
|
||||||
|
|
||||||
|
// Advance to the next state
|
||||||
|
m_state = AWAITING_SOURCE_NAME_ELEMENT_END;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AWAITING_SOURCE_URL_DATA:
|
||||||
|
// Consume the data
|
||||||
|
m_casaIdentToken.m_sourceUrl = new String(ch, start, length);
|
||||||
|
|
||||||
|
// Advance to the next state
|
||||||
|
m_state = AWAITING_SOURCE_URL_ELEMENT_END;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AWAITING_TARGET_SERVICE_DATA:
|
||||||
|
// Consume the data
|
||||||
|
m_casaIdentToken.m_service = new String(ch, start, length);
|
||||||
|
|
||||||
|
// Advance to the next state
|
||||||
|
m_state = AWAITING_TARGET_SERVICE_ELEMENT_END;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AWAITING_TARGET_HOST_DATA:
|
||||||
|
// Consume the data
|
||||||
|
m_casaIdentToken.m_host = new String(ch, start, length);
|
||||||
|
|
||||||
|
// At this point we now have the target service and host names,
|
||||||
|
// check if our configuration says that the attributes have been
|
||||||
|
// encrypted.
|
||||||
|
m_encryptedAttrs = EncryptAttributes(m_service, m_host);
|
||||||
|
|
||||||
|
// Advance to the next state
|
||||||
|
m_state = AWAITING_TARGET_HOST_ELEMENT_END;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AWAITING_ATTRIBUTE_DATA:
|
||||||
|
// Consume the data
|
||||||
|
//
|
||||||
|
// Decrypt the attribute data if necessary
|
||||||
|
if (m_encryptedAttrs)
|
||||||
|
{
|
||||||
|
// tbd - Decrypt the attribute key and value with the private key of the service
|
||||||
|
// using the configured mechanism.
|
||||||
|
m_casaIdentToken.m_attributes.put(m_currAttribute, new String(ch, start, length));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_casaIdentToken.m_attributes.put(m_currAttribute, new String(ch, start, length));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Advance to the next state
|
||||||
|
m_state = AWAITING_ATTRIBUTE_END;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
// Do nothing
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Constructor.
|
||||||
|
*/
|
||||||
|
public CasaIdentityToken ()
|
||||||
|
{
|
||||||
|
// Initialize our members
|
||||||
|
m_token = null;
|
||||||
|
m_attributes = new javax.naming.directory.BasicAttributes();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialize with parameters.
|
||||||
|
*/
|
||||||
|
public void initialize (
|
||||||
|
String identityId,
|
||||||
|
String sourceName,
|
||||||
|
String targetService,
|
||||||
|
String targetHost) throws Exception
|
||||||
|
{
|
||||||
|
// Save input parameters
|
||||||
|
m_identityId = identityId;
|
||||||
|
m_sourceName = sourceName;
|
||||||
|
m_sourceUrl = "ldap://jcserver.provo.novell.com:389"; // tbd - Obtain from config or Higgins
|
||||||
|
m_service = targetService;
|
||||||
|
m_host = targetHost;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// tbd - Read parameters from configuration and leverage Higgins.
|
||||||
|
//
|
||||||
|
// Open a directory context and use it to read the identity attributes.
|
||||||
|
Hashtable env = new Hashtable();
|
||||||
|
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
|
||||||
|
env.put(Context.PROVIDER_URL, "ldap://jcserver.provo.novell.com:389");
|
||||||
|
env.put(Context.SECURITY_AUTHENTICATION, "simple");
|
||||||
|
env.put(Context.SECURITY_PRINCIPAL, "cn=admin,o=novell");
|
||||||
|
env.put(Context.SECURITY_CREDENTIALS, "novell");
|
||||||
|
|
||||||
|
DirContext ctx = new InitialDirContext(env);
|
||||||
|
|
||||||
|
// Setup a string buffer for building the IdentityToken, notice for now
|
||||||
|
// we are not going to wrap the identity token.
|
||||||
|
StringBuffer sb = new StringBuffer();
|
||||||
|
sb.append(ProtoDefs.xmlDeclaration + "\r\n");
|
||||||
|
sb.append("<" + casaIdentTokElementName + ">" + "\r\n");
|
||||||
|
sb.append("<" + idElementName + ">" + identityId + "</" + idElementName + ">\r\n");
|
||||||
|
sb.append("<" + sourceNameElementName + ">" + sourceName + "</" + sourceNameElementName + ">\r\n");
|
||||||
|
sb.append("<" + sourceUrlElementName + ">" + m_sourceUrl + "</" + sourceUrlElementName + ">\r\n");
|
||||||
|
sb.append("<" + targetServiceElementName + ">" + m_service + "</" + targetServiceElementName + ">\r\n");
|
||||||
|
sb.append("<" + targetHostElementName + ">" + m_host + "</" + targetHostElementName + ">\r\n");
|
||||||
|
sb.append("<" + attributesElementName + ">" + "\r\n");
|
||||||
|
|
||||||
|
// Get the necessary attributes of the specified services in the identity token
|
||||||
|
Set attributesNeeded = getAttributesNeededByService(m_service, m_host);
|
||||||
|
boolean encryptAttributes = EncryptAttributes(m_service, m_host);
|
||||||
|
Attributes attrs = ctx.getAttributes(identityId);
|
||||||
|
for (NamingEnumeration ae = attrs.getAll(); ae.hasMore();)
|
||||||
|
{
|
||||||
|
javax.naming.directory.Attribute attr = (javax.naming.directory.Attribute) ae.next();
|
||||||
|
|
||||||
|
// Append the attribute if it is one that we want.
|
||||||
|
// tbd - This needs to be customized on a per service basis.
|
||||||
|
if (attributesNeeded.contains(attr.getID()))
|
||||||
|
{
|
||||||
|
NamingEnumeration enumeration = attr.getAll();
|
||||||
|
while (enumeration.hasMore())
|
||||||
|
{
|
||||||
|
String attrValue = (String) enumeration.next();
|
||||||
|
m_attributes.put(attr.getID(), attrValue);
|
||||||
|
|
||||||
|
// Encrypt the attribute if necessary
|
||||||
|
if (encryptAttributes == true)
|
||||||
|
{
|
||||||
|
// tbd - Encrypt the attributes using the services public key, let the mechanism
|
||||||
|
// be configurable.
|
||||||
|
sb.append("<" + attr.getID() + ">" + attrValue + "</" + attr.getID() + ">" + "\r\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sb.append("<" + attr.getID() + ">" + attrValue + "</" + attr.getID() + ">" + "\r\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sb.append("</" + attributesElementName + ">" + "\r\n");
|
||||||
|
sb.append("</" + casaIdentTokElementName + ">" + "\r\n");
|
||||||
|
|
||||||
|
m_token = sb.toString();
|
||||||
|
}
|
||||||
|
catch (NamingException e)
|
||||||
|
{
|
||||||
|
// tbd - Log the event???
|
||||||
|
System.err.println("CasaIdentityToken.initialize()- Naming Exception on Proxy User: " + e.getExplanation());
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
// tbd
|
||||||
|
System.err.println("CasaIdentityToken.initialize()- Exception: " + e.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialize the token object with an ecoded token string.
|
||||||
|
*/
|
||||||
|
public void initialize (String encodedToken) throws Exception
|
||||||
|
{
|
||||||
|
// Save copy of the token
|
||||||
|
m_token = Base64Coder.decode(encodedToken);
|
||||||
|
|
||||||
|
// Now parse the token into its elements
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Parse the AuthReqMsg
|
||||||
|
XMLReader xr = XMLReaderFactory.createXMLReader();
|
||||||
|
SAXHandler handler = new SAXHandler(this);
|
||||||
|
xr.setContentHandler(handler);
|
||||||
|
xr.setErrorHandler(handler);
|
||||||
|
|
||||||
|
|
||||||
|
ByteArrayInputStream inStream = new ByteArrayInputStream(m_token.getBytes());
|
||||||
|
InputSource source = new InputSource(inStream);
|
||||||
|
xr.parse(source);
|
||||||
|
}
|
||||||
|
catch (SAXException e)
|
||||||
|
{
|
||||||
|
// tbd - Log this.
|
||||||
|
System.err.println("CasaIdentityToken()- Parse exception: " + e.toString());
|
||||||
|
throw new Exception("Token error");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return the attributes needed by the service.
|
||||||
|
*/
|
||||||
|
private Set getAttributesNeededByService(String serviceName, String hostName)
|
||||||
|
{
|
||||||
|
// tbd - Read the following from configuration
|
||||||
|
HashSet attributesNeeded = new HashSet();
|
||||||
|
attributesNeeded.add("sn");
|
||||||
|
attributesNeeded.add("groupMembership");
|
||||||
|
attributesNeeded.add("securityEquals");
|
||||||
|
attributesNeeded.add("uid");
|
||||||
|
attributesNeeded.add("uidNumber");
|
||||||
|
attributesNeeded.add("gidNumber");
|
||||||
|
|
||||||
|
return attributesNeeded;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return indication of whether or not the identity attributes must be encrypted.
|
||||||
|
*/
|
||||||
|
private boolean EncryptAttributes(String serviceName, String hostName)
|
||||||
|
{
|
||||||
|
// tbd - Based return value based on the configuration for the service.
|
||||||
|
// Default is "false".
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns encoded token string.
|
||||||
|
*
|
||||||
|
* IMPORTANT: The token string can not contain the substring "]]>"
|
||||||
|
* within it.
|
||||||
|
*/
|
||||||
|
public String getEncodedToken() throws Exception
|
||||||
|
{
|
||||||
|
if (m_token != null)
|
||||||
|
{
|
||||||
|
return Base64Coder.encode(m_token);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
System.err.println("CasaIdentityToken.toString()- Not initialized");
|
||||||
|
throw new Exception("Not initialized");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns a string containing our type of identity token provider.
|
||||||
|
*/
|
||||||
|
public String getProviderType() throws Exception
|
||||||
|
{
|
||||||
|
// tbd - Change to a GUID
|
||||||
|
return "CasaIdentityToken";
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns a string containing the identity id.
|
||||||
|
*/
|
||||||
|
public String getIdentityId() throws Exception
|
||||||
|
{
|
||||||
|
if (m_identityId != null)
|
||||||
|
return m_identityId;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
System.err.println("CasaIdentityToken.getIdentityId()- Not initialized");
|
||||||
|
throw new Exception("Not initialized");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns a string containing the name associated with the
|
||||||
|
* identity source.
|
||||||
|
*/
|
||||||
|
public String getSourceName() throws Exception
|
||||||
|
{
|
||||||
|
if (m_sourceName != null)
|
||||||
|
return m_sourceName;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
System.err.println("CasaIdentityToken.getSourceName()- Not initialized");
|
||||||
|
throw new Exception("Not initialized");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns a string containing the url associated with the
|
||||||
|
* identity source.
|
||||||
|
*/
|
||||||
|
public String getSourceUrl() throws Exception
|
||||||
|
{
|
||||||
|
if (m_sourceUrl != null)
|
||||||
|
return m_sourceUrl;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
System.err.println("CasaIdentityToken.getSourceUrl()- Not initialized");
|
||||||
|
throw new Exception("Not initialized");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns a string containing the name of the targeted service.
|
||||||
|
*/
|
||||||
|
public String getTargetService() throws Exception
|
||||||
|
{
|
||||||
|
if (m_service != null)
|
||||||
|
return m_service;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
System.err.println("CasaIdentityToken.getTargetService()- Not initialized");
|
||||||
|
throw new Exception("Not initialized");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns a string containig the name of the host where the
|
||||||
|
* targeted service resides.
|
||||||
|
*/
|
||||||
|
public String getTargetHost() throws Exception
|
||||||
|
{
|
||||||
|
if (m_host != null)
|
||||||
|
return m_host;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
System.err.println("CasaIdentityToken.getTargetHost()- Not initialized");
|
||||||
|
throw new Exception("Not initialized");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns the attributes of the identity.
|
||||||
|
*/
|
||||||
|
public javax.naming.directory.Attributes getAttributes() throws Exception
|
||||||
|
{
|
||||||
|
if (m_attributes != null)
|
||||||
|
return m_attributes;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
System.err.println("CasaIdentityToken.getIdentityAttributes()- Not initialized");
|
||||||
|
throw new Exception("Not initialized");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,137 @@
|
|||||||
|
/***********************************************************************
|
||||||
|
*
|
||||||
|
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; version 2.1
|
||||||
|
* of the License.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Library Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, Novell, Inc.
|
||||||
|
*
|
||||||
|
* To contact Novell about this file by physical or electronic mail,
|
||||||
|
* you may find current contact information at www.novell.com.
|
||||||
|
*
|
||||||
|
* Author: Juan Carlos Luciani <jluciani@novell.com>
|
||||||
|
*
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
package com.novell.casa.authserver;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GetAuthPolicy Servlet Class.
|
||||||
|
*
|
||||||
|
* This class processes authentication policy requests for a particular
|
||||||
|
* service.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class GetAuthPolicy extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet
|
||||||
|
{
|
||||||
|
private static final long serialVersionUID = -8264027868130334613L;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Constructor.
|
||||||
|
*/
|
||||||
|
public GetAuthPolicy()
|
||||||
|
{
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* doGet() implementation.
|
||||||
|
*/
|
||||||
|
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
|
||||||
|
{
|
||||||
|
|
||||||
|
doPost(request, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* doPost() implementation.
|
||||||
|
*/
|
||||||
|
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
|
||||||
|
{
|
||||||
|
// Get ready to send back a reply
|
||||||
|
response.setContentType("text/html");
|
||||||
|
PrintWriter out = response.getWriter();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Read and parse the GetAuthPolicyReqMsg sent from the client
|
||||||
|
InputStream inStream = request.getInputStream();
|
||||||
|
GetAuthPolicyReqMsg getAuthPolicyReqMsg = new GetAuthPolicyReqMsg(inStream);
|
||||||
|
|
||||||
|
// Get the auth policy for the service
|
||||||
|
byte[] authPolicy = getAuthPolicyFileData(getAuthPolicyReqMsg.getServiceName(),
|
||||||
|
getAuthPolicyReqMsg.getHostName());
|
||||||
|
|
||||||
|
// Write out the response
|
||||||
|
GetAuthPolicyRespMsg getAuthPolicyRespMsg = new GetAuthPolicyRespMsg(ProtoDefs.httpOkStatusMsg,
|
||||||
|
ProtoDefs.httpOkStatusCode,
|
||||||
|
new String(Base64Coder.encode(authPolicy)));
|
||||||
|
out.println(getAuthPolicyRespMsg.toString());
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
// tbd
|
||||||
|
System.err.println("GetAuthPolicy.doPost()- Exception caught: " + e.toString());
|
||||||
|
|
||||||
|
// Write out the response
|
||||||
|
try
|
||||||
|
{
|
||||||
|
GetAuthPolicyRespMsg getAuthPolicyRespMsg = new GetAuthPolicyRespMsg(ProtoDefs.httpServerErrorStatusMsg,
|
||||||
|
ProtoDefs.httpServerErrorStatusCode);
|
||||||
|
out.println(getAuthPolicyRespMsg.toString());
|
||||||
|
}
|
||||||
|
catch (Exception e2)
|
||||||
|
{
|
||||||
|
System.err.println("GetAuthPolicy.doPost()- Exception trying to construct response msg: " + e2.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Done sending out the reply
|
||||||
|
out.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns the data associated with the authentication policy file
|
||||||
|
* associated with the specified service.
|
||||||
|
*/
|
||||||
|
private byte[] getAuthPolicyFileData(String serviceName, String hostName)
|
||||||
|
{
|
||||||
|
// tdb - Read the file associated with the specified service
|
||||||
|
StringBuffer sb = new StringBuffer();
|
||||||
|
|
||||||
|
// Start building the policy data
|
||||||
|
sb.append(ProtoDefs.xmlDeclaration + "\r\n");
|
||||||
|
sb.append("<" + ProtoDefs.authPolicyElementName + ">" + "\r\n");
|
||||||
|
sb.append("<" + ProtoDefs.authSourceElementName + ">" + "\r\n");
|
||||||
|
sb.append("<" + ProtoDefs.realmElementName + ">" + "jctree" + "</" + ProtoDefs.realmElementName + ">" + "\r\n");
|
||||||
|
sb.append("<" + ProtoDefs.mechanismElementName + ">" + "Krb5Authenticate" + "</" + ProtoDefs.mechanismElementName + ">" + "\r\n");
|
||||||
|
sb.append("<" + ProtoDefs.mechanismInfoElementName + ">" + "host/jcstation.dnsdhcp.provo.novell.com" + "</" + ProtoDefs.mechanismInfoElementName + ">" + "\r\n");
|
||||||
|
sb.append("</" + ProtoDefs.authSourceElementName + ">" + "\r\n");
|
||||||
|
sb.append("<" + ProtoDefs.authSourceElementName + ">" + "\r\n");
|
||||||
|
sb.append("<" + ProtoDefs.realmElementName + ">" + "jctree" + "</" + ProtoDefs.realmElementName + ">" + "\r\n");
|
||||||
|
sb.append("<" + ProtoDefs.mechanismElementName + ">" + "PwdAuthenticate" + "</" + ProtoDefs.mechanismElementName + ">" + "\r\n");
|
||||||
|
sb.append("<" + ProtoDefs.mechanismInfoElementName + ">" + "" + "</" + ProtoDefs.mechanismInfoElementName + ">" + "\r\n");
|
||||||
|
sb.append("</" + ProtoDefs.authSourceElementName + ">" + "\r\n");
|
||||||
|
sb.append("</" + ProtoDefs.authPolicyElementName + ">" + "\r\n");
|
||||||
|
String s = sb.toString();
|
||||||
|
return s.getBytes();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,278 @@
|
|||||||
|
/***********************************************************************
|
||||||
|
*
|
||||||
|
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; version 2.1
|
||||||
|
* of the License.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Library Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, Novell, Inc.
|
||||||
|
*
|
||||||
|
* To contact Novell about this file by physical or electronic mail,
|
||||||
|
* you may find current contact information at www.novell.com.
|
||||||
|
*
|
||||||
|
* Author: Juan Carlos Luciani <jluciani@novell.com>
|
||||||
|
*
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
package com.novell.casa.authserver;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
|
||||||
|
import org.xml.sax.InputSource;
|
||||||
|
import org.xml.sax.SAXException;
|
||||||
|
import org.xml.sax.XMLReader;
|
||||||
|
import org.xml.sax.helpers.XMLReaderFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GetAuthPolicyReqMsg Class.
|
||||||
|
*
|
||||||
|
* This class deals with the message sent by Casa Client when requesting
|
||||||
|
* authenication policy to authenticate an entity to a particular service.
|
||||||
|
* The format of the the message is as follows:
|
||||||
|
*
|
||||||
|
* <?xml version="1.0" encoding="ISO-8859-1"?>
|
||||||
|
* <get_auth_policy_req>
|
||||||
|
* <service>service name</service>
|
||||||
|
* <host>host name</host>
|
||||||
|
* </get_auth_policy_req>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class GetAuthPolicyReqMsg {
|
||||||
|
|
||||||
|
protected String m_serviceName = null;
|
||||||
|
protected String m_hostName = null;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Class for handling GetAuthPolicyReq msg parsing events.
|
||||||
|
*/
|
||||||
|
private class SAXHandler extends org.xml.sax.helpers.DefaultHandler
|
||||||
|
{
|
||||||
|
private final static int AWAITING_ROOT_ELEMENT_START = 0;
|
||||||
|
private final static int AWAITING_ROOT_ELEMENT_END = 1;
|
||||||
|
private final static int AWAITING_SERVICE_ELEMENT_START = 2;
|
||||||
|
private final static int AWAITING_SERVICE_ELEMENT_END = 3;
|
||||||
|
private final static int AWAITING_SERVICE_DATA = 4;
|
||||||
|
private final static int AWAITING_HOST_ELEMENT_START = 5;
|
||||||
|
private final static int AWAITING_HOST_ELEMENT_END = 6;
|
||||||
|
private final static int AWAITING_HOST_DATA = 7;
|
||||||
|
private final static int DONE_PARSING = 8;
|
||||||
|
|
||||||
|
private GetAuthPolicyReqMsg m_GetAuthPolicyReqMsg;
|
||||||
|
private int m_state;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Constructor
|
||||||
|
*/
|
||||||
|
public SAXHandler (GetAuthPolicyReqMsg GetAuthPolicyReqMsg)
|
||||||
|
{
|
||||||
|
super();
|
||||||
|
|
||||||
|
// Initialize our members
|
||||||
|
m_GetAuthPolicyReqMsg = GetAuthPolicyReqMsg;
|
||||||
|
m_state = AWAITING_ROOT_ELEMENT_START;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* endDocument() implementation.
|
||||||
|
*/
|
||||||
|
public void endDocument () throws SAXException
|
||||||
|
{
|
||||||
|
// Verify that we obtained all of the required elements
|
||||||
|
if (m_state != DONE_PARSING)
|
||||||
|
{
|
||||||
|
System.err.println("GetAuthPolicyReqMsg SAXHandler.endDocument()- Missing element");
|
||||||
|
throw new SAXException("Missing element");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* startElement() implementation.
|
||||||
|
*/
|
||||||
|
public void startElement (String uri, String name, String qName, org.xml.sax.Attributes atts) throws SAXException
|
||||||
|
{
|
||||||
|
// Proceed based on our state
|
||||||
|
switch (m_state) {
|
||||||
|
|
||||||
|
case AWAITING_ROOT_ELEMENT_START:
|
||||||
|
// Verify that we are processing the expected tag
|
||||||
|
if (ProtoDefs.getAuthPolicyRequestElementName.equals(qName))
|
||||||
|
{
|
||||||
|
// Advance to the next state
|
||||||
|
m_state = AWAITING_SERVICE_ELEMENT_START;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
System.err.println("GetAuthPolicyReqMsg SAXHandler.startElement()- Un-expected element");
|
||||||
|
throw new SAXException("Un-expected element");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AWAITING_SERVICE_ELEMENT_START:
|
||||||
|
// Verify that we are processing the expected tag
|
||||||
|
if (ProtoDefs.serviceElementName.equals(qName))
|
||||||
|
{
|
||||||
|
// Advance to the next state
|
||||||
|
m_state = AWAITING_SERVICE_DATA;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
System.err.println("GetAuthPolicyReqMsg SAXHandler.startElement()- Un-expected element");
|
||||||
|
throw new SAXException("Un-expected element");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AWAITING_HOST_ELEMENT_START:
|
||||||
|
// Verify that we are processing the expected tag
|
||||||
|
if (ProtoDefs.hostElementName.equals(qName))
|
||||||
|
{
|
||||||
|
// Advance to the next state
|
||||||
|
m_state = AWAITING_HOST_DATA;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
System.err.println("GetAuthPolicyReqMsg SAXHandler.startElement()- Un-expected element");
|
||||||
|
throw new SAXException("Un-expected element");
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
System.err.println("GetAuthPolicyReqMsg SAXHandler.startElement()- State error");
|
||||||
|
throw new SAXException("State error");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* endElement() immplementation.
|
||||||
|
*/
|
||||||
|
public void endElement (String uri, String name, String qName) throws SAXException
|
||||||
|
{
|
||||||
|
// Proceed based on our state
|
||||||
|
switch (m_state) {
|
||||||
|
|
||||||
|
case AWAITING_ROOT_ELEMENT_END:
|
||||||
|
// Verify that we are processing the expected tag
|
||||||
|
if (ProtoDefs.getAuthPolicyRequestElementName.equals(qName))
|
||||||
|
{
|
||||||
|
// Advance to the next state
|
||||||
|
m_state = DONE_PARSING;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
System.err.println("GetAuthPolicyReqMsg SAXHandler.endElement()- Un-expected element");
|
||||||
|
throw new SAXException("Un-expected element");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AWAITING_SERVICE_ELEMENT_END:
|
||||||
|
// Verify that we are processing the expected tag
|
||||||
|
if (ProtoDefs.serviceElementName.equals(qName))
|
||||||
|
{
|
||||||
|
// Advance to the next state
|
||||||
|
m_state = AWAITING_HOST_ELEMENT_START;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
System.err.println("GetAuthPolicyReqMsg SAXHandler.endElement()- Un-expected element");
|
||||||
|
throw new SAXException("Un-expected element");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AWAITING_HOST_ELEMENT_END:
|
||||||
|
// Verify that we are processing the expected tag
|
||||||
|
if (ProtoDefs.hostElementName.equals(qName))
|
||||||
|
{
|
||||||
|
// Advance to the next state
|
||||||
|
m_state = AWAITING_ROOT_ELEMENT_END;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
System.err.println("GetAuthPolicyReqMsg SAXHandler.endElement()- Un-expected element");
|
||||||
|
throw new SAXException("Un-expected element");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
System.err.println("GetAuthPolicyReqMsg SAXHandler.startElement()- State error");
|
||||||
|
throw new SAXException("State error");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* character() implementation.
|
||||||
|
*/
|
||||||
|
public void characters (char ch[], int start, int length) throws SAXException
|
||||||
|
{
|
||||||
|
// Proceed based on our state
|
||||||
|
switch (m_state) {
|
||||||
|
|
||||||
|
case AWAITING_SERVICE_DATA:
|
||||||
|
// Consume the data
|
||||||
|
m_GetAuthPolicyReqMsg.m_serviceName = new String(ch, start, length);
|
||||||
|
|
||||||
|
// Advance to the next state
|
||||||
|
m_state = AWAITING_SERVICE_ELEMENT_END;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AWAITING_HOST_DATA:
|
||||||
|
// Consume the data
|
||||||
|
m_GetAuthPolicyReqMsg.m_hostName = new String(ch, start, length);
|
||||||
|
|
||||||
|
// Advance to the next state
|
||||||
|
m_state = AWAITING_HOST_ELEMENT_END;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
// Do nothing
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Constructor
|
||||||
|
*/
|
||||||
|
public GetAuthPolicyReqMsg (InputStream inStream) throws Exception
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Parse the GetAuthPolicyReqMsg
|
||||||
|
XMLReader xr = XMLReaderFactory.createXMLReader();
|
||||||
|
SAXHandler handler = new SAXHandler(this);
|
||||||
|
xr.setContentHandler(handler);
|
||||||
|
xr.setErrorHandler(handler);
|
||||||
|
|
||||||
|
InputSource source = new InputSource(inStream);
|
||||||
|
xr.parse(source);
|
||||||
|
}
|
||||||
|
catch (SAXException e)
|
||||||
|
{
|
||||||
|
System.err.println("GetAuthPolicyReqMsg()- Parse exception: " + e.toString());
|
||||||
|
throw new Exception("Protocol error");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Method to get the service name.
|
||||||
|
*/
|
||||||
|
public String getServiceName() throws Exception
|
||||||
|
{
|
||||||
|
return m_serviceName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Method to get the host name.
|
||||||
|
*/
|
||||||
|
public String getHostName() throws Exception
|
||||||
|
{
|
||||||
|
return m_hostName;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,110 @@
|
|||||||
|
/***********************************************************************
|
||||||
|
*
|
||||||
|
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; version 2.1
|
||||||
|
* of the License.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Library Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, Novell, Inc.
|
||||||
|
*
|
||||||
|
* To contact Novell about this file by physical or electronic mail,
|
||||||
|
* you may find current contact information at www.novell.com.
|
||||||
|
*
|
||||||
|
* Author: Juan Carlos Luciani <jluciani@novell.com>
|
||||||
|
*
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
package com.novell.casa.authserver;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GetAuthPolicyRespMsg Class.
|
||||||
|
*
|
||||||
|
* This class deals with the message sent to the Casa Client as a
|
||||||
|
* response to a get authentication token request. The format of
|
||||||
|
* the message is as follows when the response includes an
|
||||||
|
* authentication token:
|
||||||
|
*
|
||||||
|
* <?xml version="1.0" encoding="ISO-8859-1"?>
|
||||||
|
* <get_auth_policy_resp>
|
||||||
|
* <status><description>OK</description>200</status>
|
||||||
|
* <auth_policy>authentication policy data</auth_policy>
|
||||||
|
* </get_auth_policy_resp>
|
||||||
|
*
|
||||||
|
* The format of the message is as follows when the response does not
|
||||||
|
* include an authentication token.
|
||||||
|
*
|
||||||
|
* <?xml version="1.0" encoding="ISO-8859-1"?>
|
||||||
|
* <get_auth_policy_resp>
|
||||||
|
* <status><description>status description</description>status code</status>
|
||||||
|
* </get_auth_policy_resp>
|
||||||
|
*
|
||||||
|
* Plase note that the protocol utilizes the status codes defined
|
||||||
|
* in the HTTP 1.1 Specification.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class GetAuthPolicyRespMsg {
|
||||||
|
|
||||||
|
String m_msg;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Constructor for a msg that does not include the authentication policy.
|
||||||
|
*/
|
||||||
|
public GetAuthPolicyRespMsg (
|
||||||
|
String statusDescription,
|
||||||
|
String statusCode) throws Exception
|
||||||
|
{
|
||||||
|
// Get a StringBuffer to help us with the construction of the message
|
||||||
|
StringBuffer sb = new StringBuffer();
|
||||||
|
|
||||||
|
// Start building the message
|
||||||
|
sb.append(ProtoDefs.xmlDeclaration + "\r\n");
|
||||||
|
sb.append("<" + ProtoDefs.getAuthPolicyResponseElementName + ">" + "\r\n");
|
||||||
|
sb.append("<" + ProtoDefs.statusElementName + ">"
|
||||||
|
+ "<" + ProtoDefs.descriptionElementName + ">" + statusDescription + "</" + ProtoDefs.descriptionElementName + ">"
|
||||||
|
+ statusCode + "</" + ProtoDefs.statusElementName + ">" + "\r\n");
|
||||||
|
sb.append("</" + ProtoDefs.getAuthPolicyResponseElementName + ">" + "\r\n");
|
||||||
|
|
||||||
|
// The message has now been built, save it.
|
||||||
|
m_msg = sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Constructor for a msg that includes the authentication policy.
|
||||||
|
*/
|
||||||
|
public GetAuthPolicyRespMsg (
|
||||||
|
String statusDescription,
|
||||||
|
String statusCode,
|
||||||
|
String authPolicy) throws Exception
|
||||||
|
{
|
||||||
|
// Get a StringBuffer to help us with the construction of the message
|
||||||
|
StringBuffer sb = new StringBuffer();
|
||||||
|
|
||||||
|
// Start building the message
|
||||||
|
sb.append(ProtoDefs.xmlDeclaration + "\r\n");
|
||||||
|
sb.append("<" + ProtoDefs.getAuthPolicyResponseElementName + ">" + "\r\n");
|
||||||
|
sb.append("<" + ProtoDefs.statusElementName + ">"
|
||||||
|
+ "<" + ProtoDefs.descriptionElementName + ">" + ProtoDefs.httpOkStatusMsg + "</" + ProtoDefs.descriptionElementName + ">"
|
||||||
|
+ ProtoDefs.httpOkStatusCode + "</" + ProtoDefs.statusElementName + ">" + "\r\n");
|
||||||
|
sb.append("<" + ProtoDefs.authPolicyElementName + ">" + authPolicy + "</" + ProtoDefs.authPolicyElementName + ">" + "\r\n");
|
||||||
|
sb.append("</" + ProtoDefs.getAuthPolicyResponseElementName + ">" + "\r\n");
|
||||||
|
|
||||||
|
// The message has now been built, save it.
|
||||||
|
m_msg = sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns a string containing the GetAuthPolicyRespMsg.
|
||||||
|
*/
|
||||||
|
public String toString()
|
||||||
|
{
|
||||||
|
return m_msg;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,327 @@
|
|||||||
|
/***********************************************************************
|
||||||
|
*
|
||||||
|
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; version 2.1
|
||||||
|
* of the License.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Library Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, Novell, Inc.
|
||||||
|
*
|
||||||
|
* To contact Novell about this file by physical or electronic mail,
|
||||||
|
* you may find current contact information at www.novell.com.
|
||||||
|
*
|
||||||
|
* Author: Juan Carlos Luciani <jluciani@novell.com>
|
||||||
|
*
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
package com.novell.casa.authserver;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
|
||||||
|
import org.xml.sax.InputSource;
|
||||||
|
import org.xml.sax.SAXException;
|
||||||
|
import org.xml.sax.XMLReader;
|
||||||
|
import org.xml.sax.helpers.XMLReaderFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GetAuthTokReqMsg Class.
|
||||||
|
*
|
||||||
|
* This class deals with the message sent by Casa Client when requesting
|
||||||
|
* a token to authenticate an entity to a particular service. The format of
|
||||||
|
* the message is as follows:
|
||||||
|
*
|
||||||
|
* <?xml version="1.0" encoding="ISO-8859-1"?>
|
||||||
|
* <get_auth_token_req>
|
||||||
|
* <service>service name</service>
|
||||||
|
* <host>host name</host>
|
||||||
|
* <session_token>session token data</session_token>
|
||||||
|
* </get_auth_token_req>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class GetAuthTokReqMsg {
|
||||||
|
|
||||||
|
protected String m_serviceName = null;
|
||||||
|
protected String m_hostName = null;
|
||||||
|
protected String m_sessionToken = null;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Class for handling GetAuthTokReq msg parsing events.
|
||||||
|
*/
|
||||||
|
private class SAXHandler extends org.xml.sax.helpers.DefaultHandler
|
||||||
|
{
|
||||||
|
private final static int AWAITING_ROOT_ELEMENT_START = 0;
|
||||||
|
private final static int AWAITING_ROOT_ELEMENT_END = 1;
|
||||||
|
private final static int AWAITING_SERVICE_ELEMENT_START = 2;
|
||||||
|
private final static int AWAITING_SERVICE_ELEMENT_END = 3;
|
||||||
|
private final static int AWAITING_SERVICE_DATA = 4;
|
||||||
|
private final static int AWAITING_HOST_ELEMENT_START = 5;
|
||||||
|
private final static int AWAITING_HOST_ELEMENT_END = 6;
|
||||||
|
private final static int AWAITING_HOST_DATA = 7;
|
||||||
|
private final static int AWAITING_SESSION_TOKEN_ELEMENT_START = 8;
|
||||||
|
private final static int AWAITING_SESSION_TOKEN_ELEMENT_END = 9;
|
||||||
|
private final static int AWAITING_SESSION_TOKEN_DATA = 10;
|
||||||
|
private final static int DONE_PARSING = 11;
|
||||||
|
|
||||||
|
private GetAuthTokReqMsg m_GetAuthTokReqMsg;
|
||||||
|
private int m_state;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Constructor
|
||||||
|
*/
|
||||||
|
public SAXHandler (GetAuthTokReqMsg GetAuthTokReqMsg)
|
||||||
|
{
|
||||||
|
super();
|
||||||
|
|
||||||
|
// Initialize our members
|
||||||
|
m_GetAuthTokReqMsg = GetAuthTokReqMsg;
|
||||||
|
m_state = AWAITING_ROOT_ELEMENT_START;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* endDocument() implementation.
|
||||||
|
*/
|
||||||
|
public void endDocument () throws SAXException
|
||||||
|
{
|
||||||
|
// Verify that we obtained all of the required elements
|
||||||
|
if (m_state != DONE_PARSING)
|
||||||
|
{
|
||||||
|
System.err.println("GetAuthTokReqMsg SAXHandler.endDocument()- Missing element");
|
||||||
|
throw new SAXException("Missing element");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* startElement() implementation.
|
||||||
|
*/
|
||||||
|
public void startElement (String uri, String name, String qName, org.xml.sax.Attributes atts) throws SAXException
|
||||||
|
{
|
||||||
|
// Proceed based on our state
|
||||||
|
switch (m_state) {
|
||||||
|
|
||||||
|
case AWAITING_ROOT_ELEMENT_START:
|
||||||
|
// Verify that we are processing the expected tag
|
||||||
|
if (ProtoDefs.getAuthTokRequestElementName.equals(qName))
|
||||||
|
{
|
||||||
|
// Advance to the next state
|
||||||
|
m_state = AWAITING_SERVICE_ELEMENT_START;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
System.err.println("GetAuthTokReqMsg SAXHandler.startElement()- Un-expected element");
|
||||||
|
throw new SAXException("Un-expected element");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AWAITING_SERVICE_ELEMENT_START:
|
||||||
|
// Verify that we are processing the expected tag
|
||||||
|
if (ProtoDefs.serviceElementName.equals(qName))
|
||||||
|
{
|
||||||
|
// Advance to the next state
|
||||||
|
m_state = AWAITING_SERVICE_DATA;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
System.err.println("GetAuthTokReqMsg SAXHandler.startElement()- Un-expected element");
|
||||||
|
throw new SAXException("Un-expected element");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AWAITING_HOST_ELEMENT_START:
|
||||||
|
// Verify that we are processing the expected tag
|
||||||
|
if (ProtoDefs.hostElementName.equals(qName))
|
||||||
|
{
|
||||||
|
// Advance to the next state
|
||||||
|
m_state = AWAITING_HOST_DATA;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
System.err.println("GetAuthTokReqMsg SAXHandler.startElement()- Un-expected element");
|
||||||
|
throw new SAXException("Un-expected element");
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AWAITING_SESSION_TOKEN_ELEMENT_START:
|
||||||
|
// Verify that we are processing the expected tag
|
||||||
|
if (ProtoDefs.sessionTokenElementName.equals(qName))
|
||||||
|
{
|
||||||
|
// Advance to the next state
|
||||||
|
m_state = AWAITING_SESSION_TOKEN_DATA;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
System.err.println("GetAuthTokReqMsg SAXHandler.startElement()- Un-expected element");
|
||||||
|
throw new SAXException("Un-expected element");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
System.err.println("GetAuthTokReqMsg SAXHandler.startElement()- State error");
|
||||||
|
throw new SAXException("State error");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* endElement() immplementation.
|
||||||
|
*/
|
||||||
|
public void endElement (String uri, String name, String qName) throws SAXException
|
||||||
|
{
|
||||||
|
// Proceed based on our state
|
||||||
|
switch (m_state) {
|
||||||
|
|
||||||
|
case AWAITING_ROOT_ELEMENT_END:
|
||||||
|
// Verify that we are processing the expected tag
|
||||||
|
if (ProtoDefs.getAuthTokRequestElementName.equals(qName))
|
||||||
|
{
|
||||||
|
// Advance to the next state
|
||||||
|
m_state = DONE_PARSING;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
System.err.println("GetAuthTokReqMsg SAXHandler.endElement()- Un-expected element");
|
||||||
|
throw new SAXException("Un-expected element");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AWAITING_SERVICE_ELEMENT_END:
|
||||||
|
// Verify that we are processing the expected tag
|
||||||
|
if (ProtoDefs.serviceElementName.equals(qName))
|
||||||
|
{
|
||||||
|
// Advance to the next state
|
||||||
|
m_state = AWAITING_HOST_ELEMENT_START;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
System.err.println("GetAuthTokReqMsg SAXHandler.endElement()- Un-expected element");
|
||||||
|
throw new SAXException("Un-expected element");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AWAITING_HOST_ELEMENT_END:
|
||||||
|
// Verify that we are processing the expected tag
|
||||||
|
if (ProtoDefs.hostElementName.equals(qName))
|
||||||
|
{
|
||||||
|
// Advance to the next state
|
||||||
|
m_state = AWAITING_SESSION_TOKEN_ELEMENT_START;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
System.err.println("GetAuthTokReqMsg SAXHandler.endElement()- Un-expected element");
|
||||||
|
throw new SAXException("Un-expected element");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AWAITING_SESSION_TOKEN_ELEMENT_END:
|
||||||
|
// Verify that we are processing the expected tag
|
||||||
|
if (ProtoDefs.sessionTokenElementName.equals(qName))
|
||||||
|
{
|
||||||
|
// Advance to the next state
|
||||||
|
m_state = AWAITING_ROOT_ELEMENT_END;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
System.err.println("GetAuthTokReqMsg SAXHandler.endElement()- Un-expected element");
|
||||||
|
throw new SAXException("Un-expected element");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
System.err.println("GetAuthTokReqMsg SAXHandler.startElement()- State error");
|
||||||
|
throw new SAXException("State error");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* character() implementation.
|
||||||
|
*/
|
||||||
|
public void characters (char ch[], int start, int length) throws SAXException
|
||||||
|
{
|
||||||
|
// Proceed based on our state
|
||||||
|
switch (m_state) {
|
||||||
|
|
||||||
|
case AWAITING_SERVICE_DATA:
|
||||||
|
// Consume the data
|
||||||
|
m_GetAuthTokReqMsg.m_serviceName = new String(ch, start, length);
|
||||||
|
|
||||||
|
// Advance to the next state
|
||||||
|
m_state = AWAITING_SERVICE_ELEMENT_END;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AWAITING_HOST_DATA:
|
||||||
|
// Consume the data
|
||||||
|
m_GetAuthTokReqMsg.m_hostName = new String(ch, start, length);
|
||||||
|
|
||||||
|
// Advance to the next state
|
||||||
|
m_state = AWAITING_HOST_ELEMENT_END;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AWAITING_SESSION_TOKEN_DATA:
|
||||||
|
// Consume the data
|
||||||
|
m_GetAuthTokReqMsg.m_sessionToken = new String(ch, start, length);
|
||||||
|
|
||||||
|
// Advance to the next state
|
||||||
|
m_state = AWAITING_SESSION_TOKEN_ELEMENT_END;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
// Do nothing
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Constructor
|
||||||
|
*/
|
||||||
|
public GetAuthTokReqMsg (InputStream inStream) throws Exception
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Parse the GetAuthTokReqMsg
|
||||||
|
XMLReader xr = XMLReaderFactory.createXMLReader();
|
||||||
|
SAXHandler handler = new SAXHandler(this);
|
||||||
|
xr.setContentHandler(handler);
|
||||||
|
xr.setErrorHandler(handler);
|
||||||
|
|
||||||
|
InputSource source = new InputSource(inStream);
|
||||||
|
xr.parse(source);
|
||||||
|
}
|
||||||
|
catch (SAXException e)
|
||||||
|
{
|
||||||
|
System.err.println("GetAuthTokReqMsg()- Parse exception: " + e.toString());
|
||||||
|
throw new Exception("Protocol error");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Method to get the service name.
|
||||||
|
*/
|
||||||
|
public String getServiceName() throws Exception
|
||||||
|
{
|
||||||
|
return m_serviceName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Method to get the host name.
|
||||||
|
*/
|
||||||
|
public String getHostName() throws Exception
|
||||||
|
{
|
||||||
|
return m_hostName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Method to get the session token.
|
||||||
|
*/
|
||||||
|
public String getSessionToken() throws Exception
|
||||||
|
{
|
||||||
|
return m_sessionToken;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,114 @@
|
|||||||
|
/***********************************************************************
|
||||||
|
*
|
||||||
|
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; version 2.1
|
||||||
|
* of the License.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Library Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, Novell, Inc.
|
||||||
|
*
|
||||||
|
* To contact Novell about this file by physical or electronic mail,
|
||||||
|
* you may find current contact information at www.novell.com.
|
||||||
|
*
|
||||||
|
* Author: Juan Carlos Luciani <jluciani@novell.com>
|
||||||
|
*
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
package com.novell.casa.authserver;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GetAuthTokRespMsg Class.
|
||||||
|
*
|
||||||
|
* This class deals with the message sent to the Casa Client as a
|
||||||
|
* response to a get authentication token request. The format of
|
||||||
|
* the message is as follows when the response includes an
|
||||||
|
* authentication token:
|
||||||
|
*
|
||||||
|
* <?xml version="1.0" encoding="ISO-8859-1"?>
|
||||||
|
* <get_auth_tok_resp>
|
||||||
|
* <status><description>OK</description>200</status>
|
||||||
|
* <auth_token><lifetime>lifetime value</lifetime>authentication token data</auth_token>
|
||||||
|
* </get_auth_tok_resp>
|
||||||
|
*
|
||||||
|
* The format of the message is as follows when the response does not
|
||||||
|
* include an authentication token.
|
||||||
|
*
|
||||||
|
* <?xml version="1.0" encoding="ISO-8859-1"?>
|
||||||
|
* <get_auth_tok_resp>
|
||||||
|
* <status><description>status description</description>status code</status>
|
||||||
|
* </get_auth_tok_resp>
|
||||||
|
*
|
||||||
|
* Plase note that the protocol utilizes the status codes defined
|
||||||
|
* in the HTTP 1.1 Specification.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class GetAuthTokRespMsg {
|
||||||
|
|
||||||
|
String m_msg;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Constructor for a msg that does not include the authentication token.
|
||||||
|
*/
|
||||||
|
public GetAuthTokRespMsg (
|
||||||
|
String statusDescription,
|
||||||
|
String statusCode) throws Exception
|
||||||
|
{
|
||||||
|
// Get a StringBuffer to help us with the construction of the message
|
||||||
|
StringBuffer sb = new StringBuffer();
|
||||||
|
|
||||||
|
// Start building the message
|
||||||
|
sb.append(ProtoDefs.xmlDeclaration + "\r\n");
|
||||||
|
sb.append("<" + ProtoDefs.getAuthTokResponseElementName + ">" + "\r\n");
|
||||||
|
sb.append("<" + ProtoDefs.statusElementName + ">"
|
||||||
|
+ "<" + ProtoDefs.descriptionElementName + ">" + statusDescription + "</" + ProtoDefs.descriptionElementName + ">"
|
||||||
|
+ statusCode + "</" + ProtoDefs.statusElementName + ">" + "\r\n");
|
||||||
|
sb.append("</" + ProtoDefs.getAuthTokResponseElementName + ">" + "\r\n");
|
||||||
|
|
||||||
|
// The message has now been built, save it.
|
||||||
|
m_msg = sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Constructor for a msg that includes the authentication token.
|
||||||
|
*/
|
||||||
|
public GetAuthTokRespMsg (
|
||||||
|
String statusDescription,
|
||||||
|
String statusCode,
|
||||||
|
String authToken,
|
||||||
|
String authTokenLifetime) throws Exception
|
||||||
|
{
|
||||||
|
// Get a StringBuffer to help us with the construction of the message
|
||||||
|
StringBuffer sb = new StringBuffer();
|
||||||
|
|
||||||
|
// Start building the message
|
||||||
|
sb.append(ProtoDefs.xmlDeclaration + "\r\n");
|
||||||
|
sb.append("<" + ProtoDefs.getAuthTokResponseElementName + ">" + "\r\n");
|
||||||
|
sb.append("<" + ProtoDefs.statusElementName + ">"
|
||||||
|
+ "<" + ProtoDefs.descriptionElementName + ">" + ProtoDefs.httpOkStatusMsg + "</" + ProtoDefs.descriptionElementName + ">"
|
||||||
|
+ ProtoDefs.httpOkStatusCode + "</" + ProtoDefs.statusElementName + ">" + "\r\n");
|
||||||
|
sb.append("<" + ProtoDefs.authTokenElementName + ">"
|
||||||
|
+ "<" + ProtoDefs.lifetimeElementName + ">" + authTokenLifetime + "</" + ProtoDefs.lifetimeElementName + ">"
|
||||||
|
+ authToken + "</" + ProtoDefs.authTokenElementName + ">" + "\r\n");
|
||||||
|
sb.append("</" + ProtoDefs.getAuthTokResponseElementName + ">" + "\r\n");
|
||||||
|
|
||||||
|
// The message has now been built, save it.
|
||||||
|
m_msg = sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns a string containing the GetAuthTokRespMsg.
|
||||||
|
*/
|
||||||
|
public String toString()
|
||||||
|
{
|
||||||
|
return m_msg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,135 @@
|
|||||||
|
/***********************************************************************
|
||||||
|
*
|
||||||
|
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; version 2.1
|
||||||
|
* of the License.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Library Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, Novell, Inc.
|
||||||
|
*
|
||||||
|
* To contact Novell about this file by physical or electronic mail,
|
||||||
|
* you may find current contact information at www.novell.com.
|
||||||
|
*
|
||||||
|
* Author: Juan Carlos Luciani <jluciani@novell.com>
|
||||||
|
*
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
package com.novell.casa.authserver;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GetAuthToken Servlet Class.
|
||||||
|
*
|
||||||
|
* This class processes requests for tokens to authenticate an entity
|
||||||
|
* to a particular service.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class GetAuthToken extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet
|
||||||
|
{
|
||||||
|
private static final long serialVersionUID = -5792862615065914894L;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Constructor.
|
||||||
|
*/
|
||||||
|
public GetAuthToken()
|
||||||
|
{
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* doGet() implementation.
|
||||||
|
*/
|
||||||
|
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
|
||||||
|
{
|
||||||
|
// Just let doPost() handle it.
|
||||||
|
doPost(request, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* doPost() implementation.
|
||||||
|
*/
|
||||||
|
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
|
||||||
|
{
|
||||||
|
// Get ready to send back a reply
|
||||||
|
response.setContentType("text/html");
|
||||||
|
PrintWriter out = response.getWriter();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Read and parse the GetAuthTokReqMsg sent from the client
|
||||||
|
InputStream inStream = request.getInputStream();
|
||||||
|
GetAuthTokReqMsg getAuthTokReqMsg = new GetAuthTokReqMsg(inStream);
|
||||||
|
|
||||||
|
// Now create a session token (This validates the session token provided).
|
||||||
|
SessionToken sessionToken = new SessionToken(getAuthTokReqMsg.getSessionToken());
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Create the Authentication Token
|
||||||
|
AuthToken authToken = new AuthToken(sessionToken.getIdentId(),
|
||||||
|
sessionToken.getRealm(),
|
||||||
|
getAuthTokReqMsg.getServiceName(),
|
||||||
|
getAuthTokReqMsg.getHostName());
|
||||||
|
|
||||||
|
// Write out the response
|
||||||
|
GetAuthTokRespMsg getAuthTokRespMsg = new GetAuthTokRespMsg(ProtoDefs.httpOkStatusMsg,
|
||||||
|
ProtoDefs.httpOkStatusCode,
|
||||||
|
authToken.toString(),
|
||||||
|
authToken.getLifetime());
|
||||||
|
out.println(getAuthTokRespMsg.toString());
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
// tbd, use a custom exception and then set the status based
|
||||||
|
// on the type of exeption cached.
|
||||||
|
|
||||||
|
// Write out the response
|
||||||
|
try
|
||||||
|
{
|
||||||
|
GetAuthTokRespMsg getAuthTokRespMsg = new GetAuthTokRespMsg(ProtoDefs.httpServerErrorStatusMsg,
|
||||||
|
ProtoDefs.httpUnauthorizedStatusCode);
|
||||||
|
out.println(getAuthTokRespMsg.toString());
|
||||||
|
}
|
||||||
|
catch (Exception e2)
|
||||||
|
{
|
||||||
|
System.err.println("GetAuthToken.doPost()- Exception trying to construct response msg: " + e2.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
// tbd
|
||||||
|
System.err.println("GetAuthToken.doPost()- Exception caught: " + e.toString());
|
||||||
|
|
||||||
|
// Write out the response
|
||||||
|
try
|
||||||
|
{
|
||||||
|
GetAuthTokRespMsg getAuthTokRespMsg = new GetAuthTokRespMsg(ProtoDefs.httpServerErrorStatusMsg,
|
||||||
|
ProtoDefs.httpServerErrorStatusCode);
|
||||||
|
out.println(getAuthTokRespMsg.toString());
|
||||||
|
}
|
||||||
|
catch (Exception e2)
|
||||||
|
{
|
||||||
|
System.err.println("GetAuthToken.doPost()- Exception trying to construct response msg: " + e2.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Done sending out the reply
|
||||||
|
out.close();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,93 @@
|
|||||||
|
/***********************************************************************
|
||||||
|
*
|
||||||
|
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; version 2.1
|
||||||
|
* of the License.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Library Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, Novell, Inc.
|
||||||
|
*
|
||||||
|
* To contact Novell about this file by physical or electronic mail,
|
||||||
|
* you may find current contact information at www.novell.com.
|
||||||
|
*
|
||||||
|
* Author: Juan Carlos Luciani <jluciani@novell.com>
|
||||||
|
*
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
package com.novell.casa.authserver;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* IdentityTokenProvider Interface.
|
||||||
|
*
|
||||||
|
* This is the interface to Identity Token Providers.
|
||||||
|
*/
|
||||||
|
public interface IdentityToken {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialize the token with parameters.
|
||||||
|
*/
|
||||||
|
void initialize (
|
||||||
|
String identityId,
|
||||||
|
String sourceName,
|
||||||
|
String targetService,
|
||||||
|
String targetHost) throws Exception;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialize the token object with encoded token string.
|
||||||
|
*/
|
||||||
|
void initialize (String encodedToken) throws Exception;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns encoded token string.
|
||||||
|
*
|
||||||
|
* IMPORTANT: The token string can not contain the substring "]]>"
|
||||||
|
* within it.
|
||||||
|
*/
|
||||||
|
String getEncodedToken() throws Exception;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns a string containing the identity token provider type.
|
||||||
|
*/
|
||||||
|
String getProviderType() throws Exception;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns a string containing the identity id.
|
||||||
|
*/
|
||||||
|
String getIdentityId() throws Exception;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns a string containing the name associated with the
|
||||||
|
* identity source.
|
||||||
|
*/
|
||||||
|
String getSourceName() throws Exception;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns a string containing the url associated with the
|
||||||
|
* identity source.
|
||||||
|
*/
|
||||||
|
String getSourceUrl() throws Exception;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns a string containing the name of the targeted service.
|
||||||
|
*/
|
||||||
|
String getTargetService() throws Exception;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns a string containig the name of the host where the
|
||||||
|
* targeted service resides.
|
||||||
|
*/
|
||||||
|
String getTargetHost() throws Exception;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns the attributes of the identity.
|
||||||
|
*/
|
||||||
|
javax.naming.directory.Attributes getAttributes() throws Exception;
|
||||||
|
}
|
@ -0,0 +1,279 @@
|
|||||||
|
/***********************************************************************
|
||||||
|
*
|
||||||
|
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; version 2.1
|
||||||
|
* of the License.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Library Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, Novell, Inc.
|
||||||
|
*
|
||||||
|
* To contact Novell about this file by physical or electronic mail,
|
||||||
|
* you may find current contact information at www.novell.com.
|
||||||
|
*
|
||||||
|
* Author: Juan Carlos Luciani <jluciani@novell.com>
|
||||||
|
*
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
package com.novell.casa.authserver;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
import java.util.Hashtable;
|
||||||
|
|
||||||
|
import javax.naming.Context;
|
||||||
|
import javax.naming.NamingEnumeration;
|
||||||
|
import javax.naming.NamingException;
|
||||||
|
import javax.naming.directory.Attributes;
|
||||||
|
import javax.naming.directory.BasicAttribute;
|
||||||
|
import javax.naming.directory.BasicAttributes;
|
||||||
|
import javax.naming.directory.DirContext;
|
||||||
|
import javax.naming.directory.InitialDirContext;
|
||||||
|
import javax.naming.directory.SearchResult;
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
import org.ietf.jgss.GSSContext;
|
||||||
|
import org.ietf.jgss.GSSCredential;
|
||||||
|
import org.ietf.jgss.GSSException;
|
||||||
|
import org.ietf.jgss.GSSManager;
|
||||||
|
import org.ietf.jgss.GSSName;
|
||||||
|
import org.ietf.jgss.Oid;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Krb5Authenticate Servlet Class.
|
||||||
|
*
|
||||||
|
* This class processes authentication requests utilizing a kerberos-V token.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class Krb5Authenticate extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet
|
||||||
|
{
|
||||||
|
private static final long serialVersionUID = 7247746330553668339L;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* tbd - This needs to be somewhere else so that the same parameter
|
||||||
|
* can be accessed by other authentication mechanisms.
|
||||||
|
*
|
||||||
|
* Configurable operating parameters
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public String sessionTokenLifetime = "360";
|
||||||
|
|
||||||
|
/*
|
||||||
|
* GSS Long Lived variables
|
||||||
|
*/
|
||||||
|
protected GSSManager m_manager;
|
||||||
|
protected Oid m_krb5;
|
||||||
|
protected GSSName m_svcName;
|
||||||
|
protected GSSCredential m_credential;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Krb5 Token Class.
|
||||||
|
*/
|
||||||
|
private class Krb5Token
|
||||||
|
{
|
||||||
|
private String m_principalName = "";
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The format of the Krb5 token is as follows:
|
||||||
|
*
|
||||||
|
* Base64.encode(GSS-API Token data));
|
||||||
|
*/
|
||||||
|
public Krb5Token(String encodedToken, Krb5Authenticate parent) throws Exception
|
||||||
|
{
|
||||||
|
// Decode the token
|
||||||
|
char[] tokenChars = new char[encodedToken.length()];
|
||||||
|
encodedToken.getChars(0, tokenChars.length, tokenChars, 0);
|
||||||
|
byte[] tokenBytes = Base64Coder.decode(tokenChars);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Create a context and validate the token
|
||||||
|
GSSContext context = parent.m_manager.createContext(parent.m_credential);
|
||||||
|
System.err.println("tokenLength = " + tokenBytes.length);
|
||||||
|
context.acceptSecContext(tokenBytes, 0, tokenBytes.length);
|
||||||
|
|
||||||
|
// Save the principal name of the authenticated entity
|
||||||
|
GSSName principalName = context.getSrcName();
|
||||||
|
m_principalName = principalName.toString();
|
||||||
|
|
||||||
|
// Clean up
|
||||||
|
context.dispose();
|
||||||
|
}
|
||||||
|
catch(GSSException e)
|
||||||
|
{
|
||||||
|
System.err.println("Krb5Authenticate Krb5Token()- GSS Exception caught: " + e.getLocalizedMessage());
|
||||||
|
throw new Exception("Authentication Failure");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns the name of the authenticated principal
|
||||||
|
*/
|
||||||
|
public String getPrincipalName()
|
||||||
|
{
|
||||||
|
return m_principalName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Constructor
|
||||||
|
*/
|
||||||
|
public Krb5Authenticate() throws Exception
|
||||||
|
{
|
||||||
|
super();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Initalize our GSS variables
|
||||||
|
//
|
||||||
|
// Get an instance of the default GSSManager
|
||||||
|
m_manager = GSSManager.getInstance();
|
||||||
|
|
||||||
|
// Create an OID specifying the Krb5 mechanism
|
||||||
|
m_krb5 = new Oid("1.2.840.113554.1.2.2");
|
||||||
|
|
||||||
|
// Create our host based service name
|
||||||
|
// tbd - obtain the service name from configuration
|
||||||
|
//GSSName svcName = manager.createName(ourServiceName, GSSName.NT_HOSTBASED_SERVICE, krb5);
|
||||||
|
m_svcName = m_manager.createName("host@jcstation.dnsdhcp.provo.novell.com",
|
||||||
|
GSSName.NT_HOSTBASED_SERVICE,
|
||||||
|
m_krb5);
|
||||||
|
|
||||||
|
// Now acquire our credentials
|
||||||
|
m_credential = m_manager.createCredential(m_svcName,
|
||||||
|
GSSCredential.INDEFINITE_LIFETIME,
|
||||||
|
m_krb5,
|
||||||
|
GSSCredential.ACCEPT_ONLY);
|
||||||
|
}
|
||||||
|
catch(GSSException e)
|
||||||
|
{
|
||||||
|
System.err.println("Krb5Authenticate()- GSS Exception caught: " + e.getLocalizedMessage());
|
||||||
|
throw new Exception("Failed to instantiate needed GSS objects");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* doGet() implementation.
|
||||||
|
*/
|
||||||
|
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
|
||||||
|
{
|
||||||
|
doPost(request, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* doPost() implementation.
|
||||||
|
*/
|
||||||
|
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
|
||||||
|
{
|
||||||
|
// Get ready to send back a reply
|
||||||
|
response.setContentType("text/html");
|
||||||
|
PrintWriter out = response.getWriter();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Read and parse the AuthReqMsg sent from the client
|
||||||
|
InputStream inStream = request.getInputStream();
|
||||||
|
AuthReqMsg authReqMsg = new AuthReqMsg(inStream);
|
||||||
|
|
||||||
|
// Now parse the PW Token
|
||||||
|
Krb5Token krb5Token = new Krb5Token(authReqMsg.getAuthMechToken(), this);
|
||||||
|
|
||||||
|
// Open a directory context and use it to identify the users
|
||||||
|
// associated with the specified surname.
|
||||||
|
Hashtable env = new Hashtable();
|
||||||
|
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
|
||||||
|
env.put(Context.PROVIDER_URL, "ldap://jcserver.provo.novell.com:389");
|
||||||
|
env.put(Context.SECURITY_AUTHENTICATION, "simple");
|
||||||
|
env.put(Context.SECURITY_PRINCIPAL, "cn=admin,o=novell");
|
||||||
|
env.put(Context.SECURITY_CREDENTIALS, "novell");
|
||||||
|
|
||||||
|
DirContext ctx = new InitialDirContext(env);
|
||||||
|
|
||||||
|
// Now search for a user with a matching kerberos principal name
|
||||||
|
Attributes matchAttrs = new BasicAttributes(true); // ignore attribute name case
|
||||||
|
matchAttrs.put(new BasicAttribute("krbPrincipalName", krb5Token.getPrincipalName()));
|
||||||
|
|
||||||
|
NamingEnumeration answer = ctx.search("o=novell", matchAttrs);
|
||||||
|
|
||||||
|
// Proceed based on the result of the search
|
||||||
|
String identId = null;
|
||||||
|
if (answer.hasMore())
|
||||||
|
{
|
||||||
|
// The search succeeded, set the identity id.
|
||||||
|
SearchResult sr = (SearchResult)answer.next();
|
||||||
|
identId = sr.getName() + ",o=novell";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create response based on the identity resolution results
|
||||||
|
if (identId != null)
|
||||||
|
{
|
||||||
|
// An identity was resolved, get a SessionToken for it.
|
||||||
|
SessionToken sessionToken = new SessionToken(identId, authReqMsg.getRealm(), sessionTokenLifetime);
|
||||||
|
|
||||||
|
// Write out the response
|
||||||
|
AuthRespMsg authRespMsg = new AuthRespMsg(ProtoDefs.httpOkStatusMsg,
|
||||||
|
ProtoDefs.httpOkStatusCode,
|
||||||
|
sessionToken.toString(),
|
||||||
|
sessionTokenLifetime);
|
||||||
|
out.println(authRespMsg.toString());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Write out the response
|
||||||
|
AuthRespMsg authRespMsg = new AuthRespMsg(ProtoDefs.httpUnauthorizedStatusMsg,
|
||||||
|
ProtoDefs.httpUnauthorizedStatusCode);
|
||||||
|
out.println(authRespMsg.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (NamingException e)
|
||||||
|
{
|
||||||
|
// tbd
|
||||||
|
// Log the error
|
||||||
|
System.err.println("Krb5Authenticate.doPost()- Naming Exception on Proxy User: " + e.getExplanation());
|
||||||
|
|
||||||
|
// Write out the response
|
||||||
|
try
|
||||||
|
{
|
||||||
|
AuthRespMsg authRespMsg = new AuthRespMsg(ProtoDefs.httpServerErrorStatusMsg,
|
||||||
|
ProtoDefs.httpServerErrorStatusCode);
|
||||||
|
out.println(authRespMsg.toString());
|
||||||
|
}
|
||||||
|
catch (Exception e2)
|
||||||
|
{
|
||||||
|
System.err.println("Krb5Authenticate.doPost()- Exception trying to construct response msg: " + e2.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
// tbd
|
||||||
|
System.err.println("Krb5Authenticate.doPost()- Exception caught: " + e.toString());
|
||||||
|
|
||||||
|
// Write out the response
|
||||||
|
try
|
||||||
|
{
|
||||||
|
AuthRespMsg authRespMsg = new AuthRespMsg(ProtoDefs.httpServerErrorStatusMsg,
|
||||||
|
ProtoDefs.httpServerErrorStatusCode);
|
||||||
|
out.println(authRespMsg.toString());
|
||||||
|
}
|
||||||
|
catch (Exception e2)
|
||||||
|
{
|
||||||
|
System.err.println("Krb5Authenticate.doPost()- Exception trying to construct response msg: " + e2.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Done sending out the reply
|
||||||
|
out.close();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,83 @@
|
|||||||
|
/***********************************************************************
|
||||||
|
*
|
||||||
|
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; version 2.1
|
||||||
|
* of the License.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Library Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, Novell, Inc.
|
||||||
|
*
|
||||||
|
* To contact Novell about this file by physical or electronic mail,
|
||||||
|
* you may find current contact information at www.novell.com.
|
||||||
|
*
|
||||||
|
* Author: Juan Carlos Luciani <jluciani@novell.com>
|
||||||
|
*
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
package com.novell.casa.authserver;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ProDefs Class.
|
||||||
|
*
|
||||||
|
* This class contains constants utilized in the Casa Client/Server
|
||||||
|
* protocol.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class ProtoDefs {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* XML Declaration used in the Casa Client/Server protocol
|
||||||
|
*/
|
||||||
|
public final static String xmlDeclaration = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>";
|
||||||
|
|
||||||
|
/*
|
||||||
|
* XML Element Name Constants for the documents exchanged between the
|
||||||
|
* Casa Client and the Casa Server.
|
||||||
|
*/
|
||||||
|
public final static String authRequestElementName = "auth_req";
|
||||||
|
public final static String authResponseElementName = "auth_resp";
|
||||||
|
public final static String getAuthPolicyRequestElementName = "get_auth_policy_req";
|
||||||
|
public final static String getAuthPolicyResponseElementName = "get_auth_policy_resp";
|
||||||
|
public final static String getAuthTokRequestElementName = "get_auth_tok_req";
|
||||||
|
public final static String getAuthTokResponseElementName = "get_auth_tok_resp";
|
||||||
|
public final static String authMechTokenElementName = "auth_mech_token";
|
||||||
|
public final static String statusElementName = "status";
|
||||||
|
public final static String sessionTokenElementName = "session_token";
|
||||||
|
public final static String authTokenElementName = "auth_token";
|
||||||
|
public final static String authPolicyElementName = "auth_policy";
|
||||||
|
public final static String identTokenElementName = "ident_token";
|
||||||
|
public final static String lifetimeElementName = "lifetime";
|
||||||
|
public final static String signatureElementName = "signature";
|
||||||
|
public final static String typeElementName = "type";
|
||||||
|
public final static String descriptionElementName = "description";
|
||||||
|
public final static String serviceElementName = "service";
|
||||||
|
public final static String hostElementName = "host";
|
||||||
|
public final static String identIdElementName = "ident_id";
|
||||||
|
public final static String realmElementName = "realm";
|
||||||
|
public final static String authSourceElementName = "auth_source";
|
||||||
|
public final static String mechanismElementName = "mechanism";
|
||||||
|
public final static String mechanismInfoElementName = "mechanism_info";
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Configurable operating parameters
|
||||||
|
*/
|
||||||
|
public String sessionTokenLifetime = "360";
|
||||||
|
|
||||||
|
/*
|
||||||
|
* HTTP Status Codes and Messages
|
||||||
|
*/
|
||||||
|
public final static String httpOkStatusCode = "200";
|
||||||
|
public final static String httpOkStatusMsg = "OK";
|
||||||
|
public final static String httpUnauthorizedStatusCode = "401";
|
||||||
|
public final static String httpUnauthorizedStatusMsg = "Unauthorized";
|
||||||
|
public final static String httpServerErrorStatusCode = "500";
|
||||||
|
public final static String httpServerErrorStatusMsg = "Internal Server Error";
|
||||||
|
}
|
@ -0,0 +1,258 @@
|
|||||||
|
/***********************************************************************
|
||||||
|
*
|
||||||
|
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; version 2.1
|
||||||
|
* of the License.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Library Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, Novell, Inc.
|
||||||
|
*
|
||||||
|
* To contact Novell about this file by physical or electronic mail,
|
||||||
|
* you may find current contact information at www.novell.com.
|
||||||
|
*
|
||||||
|
* Author: Juan Carlos Luciani <jluciani@novell.com>
|
||||||
|
*
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
package com.novell.casa.authserver;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
import java.io.StringReader;
|
||||||
|
import java.util.Hashtable;
|
||||||
|
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
import javax.naming.Context;
|
||||||
|
import javax.naming.NamingEnumeration;
|
||||||
|
import javax.naming.directory.BasicAttribute;
|
||||||
|
import javax.naming.directory.BasicAttributes;
|
||||||
|
import javax.naming.directory.InitialDirContext;
|
||||||
|
import javax.naming.directory.DirContext;
|
||||||
|
import javax.naming.directory.Attributes;
|
||||||
|
import javax.naming.directory.SearchResult;
|
||||||
|
import javax.naming.NamingException;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PwdAuthenticate Servlet Class.
|
||||||
|
*
|
||||||
|
* This class processes authentication requests utilizing username and
|
||||||
|
* password materials.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class PwdAuthenticate extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet
|
||||||
|
{
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 3710685782114934264L;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* tbd - This needs to be somewhere else so that the same parameter
|
||||||
|
* can be accessed by other authentication mechanisms.
|
||||||
|
*
|
||||||
|
* Configurable operating parameters
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public String sessionTokenLifetime = "360";
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Password Token Class.
|
||||||
|
*/
|
||||||
|
private class PwToken
|
||||||
|
{
|
||||||
|
private String m_username = "";
|
||||||
|
private String m_password = "";
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The format of the Pw token is as follows:
|
||||||
|
*
|
||||||
|
* Base64.encode(new String("username\r\n" + "password\r\n"));
|
||||||
|
*/
|
||||||
|
public PwToken(String encodedToken) throws IOException
|
||||||
|
{
|
||||||
|
// Decode the token
|
||||||
|
String token = Base64Coder.decode(encodedToken);
|
||||||
|
|
||||||
|
BufferedReader tokenReader = new BufferedReader(new StringReader(token));
|
||||||
|
|
||||||
|
// The second line contains the "username"
|
||||||
|
m_username = tokenReader.readLine();
|
||||||
|
|
||||||
|
// The third line contains the "password"
|
||||||
|
m_password = tokenReader.readLine();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns the username
|
||||||
|
*/
|
||||||
|
public String getUsername()
|
||||||
|
{
|
||||||
|
return m_username;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns the password
|
||||||
|
*/
|
||||||
|
public String getPassword()
|
||||||
|
{
|
||||||
|
return m_password;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Constructor
|
||||||
|
*/
|
||||||
|
public PwdAuthenticate()
|
||||||
|
{
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* doGet() implementation.
|
||||||
|
*/
|
||||||
|
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
|
||||||
|
{
|
||||||
|
// Just let doPost() handle it.
|
||||||
|
doPost(request, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* doPost() implementation.
|
||||||
|
*/
|
||||||
|
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
|
||||||
|
{
|
||||||
|
// Get ready to send back a reply
|
||||||
|
response.setContentType("text/html");
|
||||||
|
PrintWriter out = response.getWriter();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Read and parse the AuthReqMsg sent from the client
|
||||||
|
InputStream inStream = request.getInputStream();
|
||||||
|
AuthReqMsg authReqMsg = new AuthReqMsg(inStream);
|
||||||
|
|
||||||
|
// Now parse the PW Token
|
||||||
|
PwToken pwToken = new PwToken(authReqMsg.getAuthMechToken());
|
||||||
|
|
||||||
|
// Open a directory context and use it to identify the users
|
||||||
|
// associated with the specified surname.
|
||||||
|
Hashtable env = new Hashtable();
|
||||||
|
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
|
||||||
|
env.put(Context.PROVIDER_URL, "ldap://jcserver.provo.novell.com:389");
|
||||||
|
env.put(Context.SECURITY_AUTHENTICATION, "simple");
|
||||||
|
env.put(Context.SECURITY_PRINCIPAL, "cn=admin,o=novell");
|
||||||
|
env.put(Context.SECURITY_CREDENTIALS, "novell");
|
||||||
|
|
||||||
|
DirContext ctx = new InitialDirContext(env);
|
||||||
|
|
||||||
|
// Now search for a user with a matching surname
|
||||||
|
Attributes matchAttrs = new BasicAttributes(true); // ignore attribute name case
|
||||||
|
matchAttrs.put(new BasicAttribute("cn", pwToken.getUsername()));
|
||||||
|
|
||||||
|
NamingEnumeration answer = ctx.search("o=novell", matchAttrs);
|
||||||
|
|
||||||
|
// Enumerate through the users returned checking the password
|
||||||
|
String identId = null;
|
||||||
|
while (answer.hasMore())
|
||||||
|
{
|
||||||
|
SearchResult sr = (SearchResult)answer.next();
|
||||||
|
|
||||||
|
System.err.println(sr.getName());
|
||||||
|
|
||||||
|
// Open a directory context for the user as a way of verifying its password
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Hashtable env2 = new Hashtable();
|
||||||
|
env2.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
|
||||||
|
env2.put(Context.PROVIDER_URL, "ldap://jcserver.provo.novell.com:389");
|
||||||
|
env2.put(Context.SECURITY_AUTHENTICATION, "simple");
|
||||||
|
env2.put(Context.SECURITY_PRINCIPAL, sr.getName() + ",o=novell");
|
||||||
|
env2.put(Context.SECURITY_CREDENTIALS, pwToken.getPassword());
|
||||||
|
|
||||||
|
if ((new InitialDirContext(env2)) != null)
|
||||||
|
{
|
||||||
|
// The password must be valid, set the identity Id.
|
||||||
|
identId = sr.getName() + ",o=novell";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (NamingException e)
|
||||||
|
{
|
||||||
|
System.err.println("PwdAuthenticate.doPost()- Naming Exception: " + e.getExplanation());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create response based on the identity resolution results
|
||||||
|
if (identId != null)
|
||||||
|
{
|
||||||
|
// An identity was resolved, get a SessionToken for it.
|
||||||
|
SessionToken sessionToken = new SessionToken(identId, authReqMsg.getRealm(), sessionTokenLifetime);
|
||||||
|
|
||||||
|
// Write out the response
|
||||||
|
AuthRespMsg authRespMsg = new AuthRespMsg(ProtoDefs.httpOkStatusMsg,
|
||||||
|
ProtoDefs.httpOkStatusCode,
|
||||||
|
sessionToken.toString(),
|
||||||
|
sessionTokenLifetime);
|
||||||
|
out.println(authRespMsg.toString());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Write out the response
|
||||||
|
AuthRespMsg authRespMsg = new AuthRespMsg(ProtoDefs.httpUnauthorizedStatusMsg,
|
||||||
|
ProtoDefs.httpUnauthorizedStatusCode);
|
||||||
|
out.println(authRespMsg.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (NamingException e)
|
||||||
|
{
|
||||||
|
// tbd
|
||||||
|
// Log the error
|
||||||
|
System.err.println("PwdAuthenticate.doPost()- Naming Exception on Proxy User: " + e.getExplanation());
|
||||||
|
|
||||||
|
// Write out the response
|
||||||
|
try
|
||||||
|
{
|
||||||
|
AuthRespMsg authRespMsg = new AuthRespMsg(ProtoDefs.httpServerErrorStatusMsg,
|
||||||
|
ProtoDefs.httpServerErrorStatusCode);
|
||||||
|
out.println(authRespMsg.toString());
|
||||||
|
}
|
||||||
|
catch (Exception e2)
|
||||||
|
{
|
||||||
|
System.err.println("PwdAuthenticate.doPost()- Exception trying to construct response msg: " + e2.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
// tbd
|
||||||
|
System.err.println("PwdAuthenticate.doPost()- Naming Exception on Proxy User: " + e.toString());
|
||||||
|
|
||||||
|
// Write out the response
|
||||||
|
try
|
||||||
|
{
|
||||||
|
AuthRespMsg authRespMsg = new AuthRespMsg(ProtoDefs.httpServerErrorStatusMsg,
|
||||||
|
ProtoDefs.httpServerErrorStatusCode);
|
||||||
|
out.println(authRespMsg.toString());
|
||||||
|
}
|
||||||
|
catch (Exception e2)
|
||||||
|
{
|
||||||
|
System.err.println("PwdAuthenticate.doPost()- Exception trying to construct response msg: " + e2.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Done sending out the reply
|
||||||
|
out.close();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,412 @@
|
|||||||
|
/***********************************************************************
|
||||||
|
*
|
||||||
|
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; version 2.1
|
||||||
|
* of the License.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Library Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, Novell, Inc.
|
||||||
|
*
|
||||||
|
* To contact Novell about this file by physical or electronic mail,
|
||||||
|
* you may find current contact information at www.novell.com.
|
||||||
|
*
|
||||||
|
* Author: Juan Carlos Luciani <jluciani@novell.com>
|
||||||
|
*
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
package com.novell.casa.authserver;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
|
||||||
|
import org.xml.sax.InputSource;
|
||||||
|
import org.xml.sax.SAXException;
|
||||||
|
import org.xml.sax.XMLReader;
|
||||||
|
import org.xml.sax.helpers.XMLReaderFactory;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SessionToken class.
|
||||||
|
*
|
||||||
|
* This class constructs session tokens that Casa clients can present to
|
||||||
|
* the Casa server to prove that an entity has been authenticated to
|
||||||
|
* a particular realm. The format of the session token is as follows:
|
||||||
|
*
|
||||||
|
* <?xml version="1.0" encoding="ISO-8859-1"?>
|
||||||
|
* <session_token>
|
||||||
|
* <signature>signature value</signature>
|
||||||
|
* <lifetime>lifetime value</lifetime>
|
||||||
|
* <realm>realm value</realm>
|
||||||
|
* <ident_id>identity id value</ident_id>
|
||||||
|
* </session_token>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class SessionToken {
|
||||||
|
|
||||||
|
private String m_id;
|
||||||
|
private String m_realm;
|
||||||
|
private String m_lifetime;
|
||||||
|
private String m_signature;
|
||||||
|
private String m_token;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Class for handling parsing events.
|
||||||
|
*/
|
||||||
|
private class SAXHandler extends org.xml.sax.helpers.DefaultHandler
|
||||||
|
{
|
||||||
|
private final static int AWAITING_ROOT_ELEMENT_START = 0;
|
||||||
|
private final static int AWAITING_ROOT_ELEMENT_END = 1;
|
||||||
|
private final static int AWAITING_SIGNATURE_ELEMENT_START = 2;
|
||||||
|
private final static int AWAITING_SIGNATURE_ELEMENT_END = 3;
|
||||||
|
private final static int AWAITING_SIGNATURE_DATA = 4;
|
||||||
|
private final static int AWAITING_LIFETIME_ELEMENT_START = 5;
|
||||||
|
private final static int AWAITING_LIFETIME_ELEMENT_END = 6;
|
||||||
|
private final static int AWAITING_LIFETIME_DATA = 7;
|
||||||
|
private final static int AWAITING_REALM_ELEMENT_START = 8;
|
||||||
|
private final static int AWAITING_REALM_ELEMENT_END = 9;
|
||||||
|
private final static int AWAITING_REALM_DATA = 10;
|
||||||
|
private final static int AWAITING_IDENT_ID_ELEMENT_START = 11;
|
||||||
|
private final static int AWAITING_IDENT_ID_ELEMENT_END = 12;
|
||||||
|
private final static int AWAITING_IDENT_ID_DATA = 13;
|
||||||
|
private final static int DONE_PARSING = 14;
|
||||||
|
|
||||||
|
private SessionToken m_SessionToken;
|
||||||
|
private int m_state;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Constructor
|
||||||
|
*/
|
||||||
|
public SAXHandler (SessionToken SessionToken)
|
||||||
|
{
|
||||||
|
super();
|
||||||
|
|
||||||
|
// Initialize our members
|
||||||
|
m_SessionToken = SessionToken;
|
||||||
|
m_state = AWAITING_ROOT_ELEMENT_START;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* endDocument() implementation.
|
||||||
|
*/
|
||||||
|
public void endDocument () throws SAXException
|
||||||
|
{
|
||||||
|
// Verify that we obtained all of the required elements
|
||||||
|
if (m_state != DONE_PARSING)
|
||||||
|
{
|
||||||
|
System.err.println("SessionToken SAXHandler.endDocument()- Missing element");
|
||||||
|
throw new SAXException("Missing element");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* startElement() implementation.
|
||||||
|
*/
|
||||||
|
public void startElement (String uri, String name, String qName, org.xml.sax.Attributes atts) throws SAXException
|
||||||
|
{
|
||||||
|
// Proceed based on our state
|
||||||
|
switch (m_state) {
|
||||||
|
|
||||||
|
case AWAITING_ROOT_ELEMENT_START:
|
||||||
|
// Verify that we are processing the expected tag
|
||||||
|
if (ProtoDefs.sessionTokenElementName.equals(qName))
|
||||||
|
{
|
||||||
|
// Advance to the next state
|
||||||
|
m_state = AWAITING_SIGNATURE_ELEMENT_START;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
System.err.println("SessionToken SAXHandler.startElement()- Un-expected element");
|
||||||
|
throw new SAXException("Un-expected element");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AWAITING_SIGNATURE_ELEMENT_START:
|
||||||
|
// Verify that we are processing the expected tag
|
||||||
|
if (ProtoDefs.signatureElementName.equals(qName))
|
||||||
|
{
|
||||||
|
// Advance to the next state
|
||||||
|
m_state = AWAITING_SIGNATURE_DATA;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
System.err.println("SessionToken SAXHandler.startElement()- Un-expected element");
|
||||||
|
throw new SAXException("Un-expected element");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AWAITING_LIFETIME_ELEMENT_START:
|
||||||
|
// Verify that we are processing the expected tag
|
||||||
|
if (ProtoDefs.lifetimeElementName.equals(qName))
|
||||||
|
{
|
||||||
|
// Advance to the next state
|
||||||
|
m_state = AWAITING_LIFETIME_DATA;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
System.err.println("SessionToken SAXHandler.startElement()- Un-expected element");
|
||||||
|
throw new SAXException("Un-expected element");
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AWAITING_REALM_ELEMENT_START:
|
||||||
|
// Verify that we are processing the expected tag
|
||||||
|
if (ProtoDefs.realmElementName.equals(qName))
|
||||||
|
{
|
||||||
|
// Advance to the next state
|
||||||
|
m_state = AWAITING_REALM_DATA;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
System.err.println("SessionToken SAXHandler.startElement()- Un-expected element");
|
||||||
|
throw new SAXException("Un-expected element");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AWAITING_IDENT_ID_ELEMENT_START:
|
||||||
|
// Verify that we are processing the expected tag
|
||||||
|
if (ProtoDefs.identIdElementName.equals(qName))
|
||||||
|
{
|
||||||
|
// Advance to the next state
|
||||||
|
m_state = AWAITING_IDENT_ID_DATA;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
System.err.println("SessionToken SAXHandler.startElement()- Un-expected element");
|
||||||
|
throw new SAXException("Un-expected element");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
System.err.println("SessionToken SAXHandler.startElement()- State error");
|
||||||
|
throw new SAXException("State error");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* endElement() immplementation.
|
||||||
|
*/
|
||||||
|
public void endElement (String uri, String name, String qName) throws SAXException
|
||||||
|
{
|
||||||
|
// Proceed based on our state
|
||||||
|
switch (m_state) {
|
||||||
|
|
||||||
|
case AWAITING_ROOT_ELEMENT_END:
|
||||||
|
// Verify that we are processing the expected tag
|
||||||
|
if (ProtoDefs.sessionTokenElementName.equals(qName))
|
||||||
|
{
|
||||||
|
// Advance to the next state
|
||||||
|
m_state = DONE_PARSING;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
System.err.println("SessionToken SAXHandler.endElement()- Un-expected element");
|
||||||
|
throw new SAXException("Un-expected element");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AWAITING_SIGNATURE_ELEMENT_END:
|
||||||
|
// Verify that we are processing the expected tag
|
||||||
|
if (ProtoDefs.signatureElementName.equals(qName))
|
||||||
|
{
|
||||||
|
// Advance to the next state
|
||||||
|
m_state = AWAITING_LIFETIME_ELEMENT_START;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
System.err.println("SessionToken SAXHandler.endElement()- Un-expected element");
|
||||||
|
throw new SAXException("Un-expected element");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AWAITING_LIFETIME_ELEMENT_END:
|
||||||
|
// Verify that we are processing the expected tag
|
||||||
|
if (ProtoDefs.lifetimeElementName.equals(qName))
|
||||||
|
{
|
||||||
|
// Advance to the next state
|
||||||
|
m_state = AWAITING_REALM_ELEMENT_START;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
System.err.println("SessionToken SAXHandler.endElement()- Un-expected element");
|
||||||
|
throw new SAXException("Un-expected element");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AWAITING_REALM_ELEMENT_END:
|
||||||
|
// Verify that we are processing the expected tag
|
||||||
|
if (ProtoDefs.realmElementName.equals(qName))
|
||||||
|
{
|
||||||
|
// Advance to the next state
|
||||||
|
m_state = AWAITING_IDENT_ID_ELEMENT_START;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
System.err.println("SessionToken SAXHandler.endElement()- Un-expected element");
|
||||||
|
throw new SAXException("Un-expected element");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AWAITING_IDENT_ID_ELEMENT_END:
|
||||||
|
// Verify that we are processing the expected tag
|
||||||
|
if (ProtoDefs.identIdElementName.equals(qName))
|
||||||
|
{
|
||||||
|
// Advance to the next state
|
||||||
|
m_state = AWAITING_ROOT_ELEMENT_END;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
System.err.println("SessionToken SAXHandler.endElement()- Un-expected element");
|
||||||
|
throw new SAXException("Un-expected element");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
System.err.println("SessionToken SAXHandler.startElement()- State error");
|
||||||
|
throw new SAXException("State error");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* character() implementation.
|
||||||
|
*/
|
||||||
|
public void characters (char ch[], int start, int length) throws SAXException
|
||||||
|
{
|
||||||
|
// Proceed based on our state
|
||||||
|
switch (m_state) {
|
||||||
|
|
||||||
|
case AWAITING_SIGNATURE_DATA:
|
||||||
|
// Consume the data
|
||||||
|
m_SessionToken.m_signature = new String(ch, start, length);
|
||||||
|
|
||||||
|
// Advance to the next state
|
||||||
|
m_state = AWAITING_SIGNATURE_ELEMENT_END;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AWAITING_LIFETIME_DATA:
|
||||||
|
// Consume the data
|
||||||
|
m_SessionToken.m_lifetime = new String(ch, start, length);
|
||||||
|
|
||||||
|
// Advance to the next state
|
||||||
|
m_state = AWAITING_LIFETIME_ELEMENT_END;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AWAITING_REALM_DATA:
|
||||||
|
// Consume the data
|
||||||
|
m_SessionToken.m_realm = new String(ch, start, length);
|
||||||
|
|
||||||
|
// Advance to the next state
|
||||||
|
m_state = AWAITING_REALM_ELEMENT_END;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AWAITING_IDENT_ID_DATA:
|
||||||
|
// Consume the data
|
||||||
|
m_SessionToken.m_id = new String(ch, start, length);
|
||||||
|
|
||||||
|
// Advance to the next state
|
||||||
|
m_state = AWAITING_IDENT_ID_ELEMENT_END;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
// Do nothing
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Constructor
|
||||||
|
*/
|
||||||
|
public SessionToken(String id, String realm, String lifetime) throws Exception
|
||||||
|
{
|
||||||
|
// Save copies of the input parameters
|
||||||
|
m_id = id;
|
||||||
|
m_realm = realm;
|
||||||
|
m_lifetime = lifetime;
|
||||||
|
|
||||||
|
// Generate a signature
|
||||||
|
// tbd - Over id, realm, and lifetime data.
|
||||||
|
m_signature = "tbd";
|
||||||
|
|
||||||
|
// Get a StringBuffer to help us with the construction of the token
|
||||||
|
StringBuffer sb = new StringBuffer();
|
||||||
|
|
||||||
|
// Start building the message
|
||||||
|
sb.append(ProtoDefs.xmlDeclaration + "\r\n");
|
||||||
|
sb.append("<" + ProtoDefs.sessionTokenElementName + ">" + "\r\n");
|
||||||
|
sb.append("<" + ProtoDefs.signatureElementName + ">" + m_signature + "</" + ProtoDefs.signatureElementName + ">" + "\r\n");
|
||||||
|
sb.append("<" + ProtoDefs.lifetimeElementName + ">" + m_lifetime + "</" + ProtoDefs.lifetimeElementName + ">" + "\r\n");
|
||||||
|
sb.append("<" + ProtoDefs.realmElementName + ">" + m_realm + "</" + ProtoDefs.realmElementName + ">" + "\r\n");
|
||||||
|
sb.append("<" + ProtoDefs.identIdElementName + ">" + m_id + "</" + ProtoDefs.identIdElementName + ">" + "\r\n");
|
||||||
|
sb.append("</" + ProtoDefs.sessionTokenElementName + ">" + "\r\n");
|
||||||
|
|
||||||
|
// Save the token
|
||||||
|
m_token = sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Constructor given a session token string. The constructor
|
||||||
|
* validates the token as part of its processing.
|
||||||
|
*/
|
||||||
|
public SessionToken(String token) throws Exception
|
||||||
|
{
|
||||||
|
// Decode the token string
|
||||||
|
m_token = Base64Coder.decode(token);
|
||||||
|
|
||||||
|
// Now parse the token into its elements
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Parse the SessionToken
|
||||||
|
XMLReader xr = XMLReaderFactory.createXMLReader();
|
||||||
|
SAXHandler handler = new SAXHandler(this);
|
||||||
|
xr.setContentHandler(handler);
|
||||||
|
xr.setErrorHandler(handler);
|
||||||
|
|
||||||
|
ByteArrayInputStream inStream = new ByteArrayInputStream(m_token.getBytes());
|
||||||
|
InputSource source = new InputSource(inStream);
|
||||||
|
xr.parse(source);
|
||||||
|
|
||||||
|
// Verify the signature
|
||||||
|
// tbd
|
||||||
|
|
||||||
|
// Verify that the token has not expired
|
||||||
|
// tbd
|
||||||
|
}
|
||||||
|
catch (SAXException e)
|
||||||
|
{
|
||||||
|
System.err.println("SessionToken()- Parse exception: " + e.toString());
|
||||||
|
throw new Exception("Protocol error");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns a string containing the session token.
|
||||||
|
*/
|
||||||
|
public String toString()
|
||||||
|
{
|
||||||
|
return Base64Coder.encode(m_token);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Method to get the Identity Id
|
||||||
|
*/
|
||||||
|
public String getIdentId() throws Exception
|
||||||
|
{
|
||||||
|
return m_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Method to get the Identity Repository Reference (Realm).
|
||||||
|
*/
|
||||||
|
public String getRealm() throws Exception
|
||||||
|
{
|
||||||
|
return m_realm;
|
||||||
|
}
|
||||||
|
}
|
7
auth_token/server/CasaJaasSupport/.classpath
Normal file
7
auth_token/server/CasaJaasSupport/.classpath
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<classpath>
|
||||||
|
<classpathentry kind="src" path="src"/>
|
||||||
|
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
|
||||||
|
<classpathentry combineaccessrules="false" kind="src" path="/CasaAuthServer"/>
|
||||||
|
<classpathentry kind="output" path="build/classes"/>
|
||||||
|
</classpath>
|
17
auth_token/server/CasaJaasSupport/.project
Normal file
17
auth_token/server/CasaJaasSupport/.project
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<projectDescription>
|
||||||
|
<name>CasaJaasSupport</name>
|
||||||
|
<comment></comment>
|
||||||
|
<projects>
|
||||||
|
</projects>
|
||||||
|
<buildSpec>
|
||||||
|
<buildCommand>
|
||||||
|
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||||
|
<arguments>
|
||||||
|
</arguments>
|
||||||
|
</buildCommand>
|
||||||
|
</buildSpec>
|
||||||
|
<natures>
|
||||||
|
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||||
|
</natures>
|
||||||
|
</projectDescription>
|
@ -0,0 +1,256 @@
|
|||||||
|
/***********************************************************************
|
||||||
|
*
|
||||||
|
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; version 2.1
|
||||||
|
* of the License.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Library Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, Novell, Inc.
|
||||||
|
*
|
||||||
|
* To contact Novell about this file by physical or electronic mail,
|
||||||
|
* you may find current contact information at www.novell.com.
|
||||||
|
*
|
||||||
|
* Author: Juan Carlos Luciani <jluciani@novell.com>
|
||||||
|
*
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
package com.novell.casa.jaas;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import javax.security.auth.Subject;
|
||||||
|
import javax.security.auth.callback.Callback;
|
||||||
|
import javax.security.auth.callback.CallbackHandler;
|
||||||
|
import javax.security.auth.callback.NameCallback;
|
||||||
|
import javax.security.auth.callback.PasswordCallback;
|
||||||
|
import javax.security.auth.login.FailedLoginException;
|
||||||
|
import javax.security.auth.login.LoginException;
|
||||||
|
import javax.security.auth.spi.LoginModule;
|
||||||
|
|
||||||
|
import com.novell.casa.authserver.AuthToken;
|
||||||
|
import com.novell.casa.authserver.CasaIdentityToken;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* CasaLoginModule Class.
|
||||||
|
*
|
||||||
|
* This class implements a LoginModule which performs
|
||||||
|
* authentication via the Casa Authentication Token
|
||||||
|
* infrastructure.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class CasaLoginModule implements LoginModule
|
||||||
|
{
|
||||||
|
private final static String casaUsername = "CasaIdentityUser";
|
||||||
|
|
||||||
|
private Subject m_subject = null;
|
||||||
|
private CasaPrincipal m_principal = null;
|
||||||
|
private CallbackHandler m_callbackHandler = null;
|
||||||
|
private Map m_sharedState = null;
|
||||||
|
private Map m_options = null;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see javax.security.auth.spi.LoginModule#abort()
|
||||||
|
*/
|
||||||
|
public boolean abort() throws LoginException
|
||||||
|
{
|
||||||
|
// Clear out all of our state
|
||||||
|
m_subject = null;
|
||||||
|
m_principal = null;
|
||||||
|
m_callbackHandler = null;
|
||||||
|
m_sharedState = null;
|
||||||
|
m_options = null;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see javax.security.auth.spi.LoginModule#commit()
|
||||||
|
*/
|
||||||
|
public boolean commit() throws LoginException
|
||||||
|
{
|
||||||
|
// Check if we instantiated a principal to associate
|
||||||
|
// with the subject.
|
||||||
|
if (m_principal != null)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Add our principal to the set associated with
|
||||||
|
// the subject.
|
||||||
|
m_subject.getPrincipals().add(m_principal);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
System.err.println("CasaLoginModule.commit()- Exception caught associating principal, msg: " + e.getMessage());
|
||||||
|
throw new LoginException("Error encountered");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Allways return since authentication failed or was not
|
||||||
|
// performed by us.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see javax.security.auth.spi.LoginModule#login()
|
||||||
|
*/
|
||||||
|
public boolean login() throws LoginException
|
||||||
|
{
|
||||||
|
// Verify that a CallbackHandler was specified
|
||||||
|
if (m_callbackHandler == null)
|
||||||
|
{
|
||||||
|
System.err.println("CasaLoginModule.login()- Null CallbackHandler");
|
||||||
|
throw new LoginException("Null CallbackHandler");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Perform the username check unless configured to skip it.
|
||||||
|
boolean skipUsernameCheck = false;
|
||||||
|
if (m_options != null
|
||||||
|
&& m_options.containsKey((String) "skipUsernameCheck") == true)
|
||||||
|
{
|
||||||
|
String keyVal = (String) m_options.get("skipUsernameCheck");
|
||||||
|
if (keyVal == null || keyVal.equals("true"))
|
||||||
|
skipUsernameCheck = true;
|
||||||
|
}
|
||||||
|
if (!skipUsernameCheck)
|
||||||
|
{
|
||||||
|
// Verify that the username is CasaIdentityUser, for this
|
||||||
|
// we first need to obtain it.
|
||||||
|
//
|
||||||
|
// Try to obtain the user name from the shared state
|
||||||
|
String username = (String) m_sharedState.get("javax.security.auth.login.name");
|
||||||
|
if (username == null)
|
||||||
|
{
|
||||||
|
// The usename was not stored in the shared state, request it.
|
||||||
|
try
|
||||||
|
{
|
||||||
|
NameCallback nameCallback = new NameCallback("Enter username:");
|
||||||
|
Callback[] callbacks = new Callback[1];
|
||||||
|
callbacks[0] = nameCallback;
|
||||||
|
m_callbackHandler.handle(callbacks);
|
||||||
|
username = nameCallback.getName();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
System.err.println("CasaLoginModule.login()- Exception caught during nameCallback, msg: " + e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check the username
|
||||||
|
if (username == null)
|
||||||
|
return false;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Save the retrieved username in the shared state and then check it.
|
||||||
|
m_sharedState.put("javax.security.auth.login.name" , username);
|
||||||
|
if (username.equals(casaUsername) == false)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Check the username
|
||||||
|
if (username.equals(casaUsername) == false)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Obtain the CasaAuthenticationToken
|
||||||
|
char[] authTokenChars = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
PasswordCallback passwordCallback = new PasswordCallback("Enter CasaAuthenticationToken:", false);
|
||||||
|
Callback[] callbacks = new Callback[1];
|
||||||
|
callbacks[0] = passwordCallback;
|
||||||
|
m_callbackHandler.handle(callbacks);
|
||||||
|
authTokenChars = passwordCallback.getPassword();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
System.err.println("CasaLoginModule.login()- Exception caught during passwordCallback, msg: " + e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check the CasaAuthenticationToken
|
||||||
|
if (authTokenChars != null)
|
||||||
|
{
|
||||||
|
// Instantiate the AuthToken, this validates the token itself.
|
||||||
|
try
|
||||||
|
{
|
||||||
|
AuthToken authToken = new AuthToken(new String(authTokenChars));
|
||||||
|
|
||||||
|
// Instantiate the appropriate IdentityToken based on the IdentityTokenProvider type
|
||||||
|
// tbd - For now use the CasaIdentityToken
|
||||||
|
CasaIdentityToken identityToken = new CasaIdentityToken();
|
||||||
|
identityToken.initialize(authToken.getIdentityToken());
|
||||||
|
|
||||||
|
// Now instantiate the CasaPrincipal
|
||||||
|
m_principal = new CasaPrincipal(identityToken);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
// The validation of one of the tokens failed
|
||||||
|
// tbd - Log
|
||||||
|
System.err.println("CasaLoginModule.login()- Exception caught during token processing, msg: " + e.getMessage());
|
||||||
|
throw new FailedLoginException("Token validation failed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Token not provided
|
||||||
|
// tbd - Log
|
||||||
|
System.err.println("CasaLoginModule.login()- Token not provided");
|
||||||
|
throw new FailedLoginException("CasaAuthenticationToken not obtained");
|
||||||
|
}
|
||||||
|
|
||||||
|
// User validated
|
||||||
|
// tbd - Log
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see javax.security.auth.spi.LoginModule#logout()
|
||||||
|
*/
|
||||||
|
public boolean logout() throws LoginException
|
||||||
|
{
|
||||||
|
// Check if we must try to remove our principal
|
||||||
|
// from the associated subject.
|
||||||
|
if (m_principal != null
|
||||||
|
&& m_subject.isReadOnly() == false)
|
||||||
|
{
|
||||||
|
Set principalSet = m_subject.getPrincipals();
|
||||||
|
principalSet.remove(m_principal);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see javax.security.auth.spi.LoginModule#initialize(javax.security.auth.Subject, javax.security.auth.callback.CallbackHandler, java.util.Map, java.util.Map)
|
||||||
|
*/
|
||||||
|
public void initialize(
|
||||||
|
Subject subject,
|
||||||
|
CallbackHandler callbackHandler,
|
||||||
|
Map sharedState,
|
||||||
|
Map options)
|
||||||
|
{
|
||||||
|
// Save the input parameters for later use
|
||||||
|
m_subject = subject;
|
||||||
|
m_callbackHandler = callbackHandler;
|
||||||
|
m_sharedState = sharedState;
|
||||||
|
m_options = options;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,86 @@
|
|||||||
|
/***********************************************************************
|
||||||
|
*
|
||||||
|
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; version 2.1
|
||||||
|
* of the License.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Library Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, Novell, Inc.
|
||||||
|
*
|
||||||
|
* To contact Novell about this file by physical or electronic mail,
|
||||||
|
* you may find current contact information at www.novell.com.
|
||||||
|
*
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
package com.novell.casa.jaas;
|
||||||
|
|
||||||
|
import java.security.Principal;
|
||||||
|
|
||||||
|
import com.novell.casa.authserver.IdentityToken;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* CasaPrincipal class.
|
||||||
|
*
|
||||||
|
* This class implements the principal class for
|
||||||
|
* identities authenticated by Casa.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class CasaPrincipal implements Principal
|
||||||
|
{
|
||||||
|
private String m_name;
|
||||||
|
private String m_realm;
|
||||||
|
private String m_identStoreUrl;
|
||||||
|
private javax.naming.directory.Attributes m_attributes;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Constructor
|
||||||
|
*/
|
||||||
|
public CasaPrincipal(IdentityToken identityToken) throws Exception
|
||||||
|
{
|
||||||
|
// Get the necessary information from the identity token
|
||||||
|
m_name = identityToken.getIdentityId();
|
||||||
|
m_realm = identityToken.getSourceName();
|
||||||
|
m_identStoreUrl = identityToken.getSourceUrl();
|
||||||
|
m_attributes = identityToken.getAttributes();
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see java.security.Principal#getName()
|
||||||
|
*/
|
||||||
|
public String getName()
|
||||||
|
{
|
||||||
|
return m_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns the name associated with the source of the identity data.
|
||||||
|
*/
|
||||||
|
public String getRealm()
|
||||||
|
{
|
||||||
|
return m_realm;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns the url associated with the source of the identity data.
|
||||||
|
*/
|
||||||
|
public String getIdentStoreUrl()
|
||||||
|
{
|
||||||
|
return m_identStoreUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns the identity attributes.
|
||||||
|
*/
|
||||||
|
public javax.naming.directory.Attributes getAttributes()
|
||||||
|
{
|
||||||
|
return m_attributes;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,3 @@
|
|||||||
|
SampleApp {
|
||||||
|
com.novell.casa.jaas.CasaLoginModule Required debug=true;
|
||||||
|
};
|
@ -0,0 +1,174 @@
|
|||||||
|
/***********************************************************************
|
||||||
|
*
|
||||||
|
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; version 2.1
|
||||||
|
* of the License.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Library Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, Novell, Inc.
|
||||||
|
*
|
||||||
|
* To contact Novell about this file by physical or electronic mail,
|
||||||
|
* you may find current contact information at www.novell.com.
|
||||||
|
*
|
||||||
|
* Author: Juan Carlos Luciani <jluciani@novell.com>
|
||||||
|
*
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
package com.novell.casa.jaas;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.net.ServerSocket;
|
||||||
|
import java.net.Socket;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import javax.naming.NamingEnumeration;
|
||||||
|
import javax.security.auth.Subject;
|
||||||
|
import javax.security.auth.login.LoginContext;
|
||||||
|
import javax.security.auth.login.LoginException;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is a sample application which demonstrates the use of
|
||||||
|
* JAAS and Casa to authenticate a connection.
|
||||||
|
*/
|
||||||
|
public class SampleApp
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @param args
|
||||||
|
*/
|
||||||
|
public static void main(String[] args)
|
||||||
|
{
|
||||||
|
Socket sock = null;
|
||||||
|
ServerSocket listenSock = null;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Create a socket to listen for connections
|
||||||
|
int port = 4444;
|
||||||
|
int queueLen = 6;
|
||||||
|
listenSock = new ServerSocket(port, queueLen);
|
||||||
|
|
||||||
|
// Service connections
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
BufferedReader in = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Wait for the next connection
|
||||||
|
System.out.println("Waiting for connection");
|
||||||
|
sock = listenSock.accept();
|
||||||
|
System.out.println();
|
||||||
|
System.out.println("********Connection received*********");
|
||||||
|
|
||||||
|
// Get socket I/O streams
|
||||||
|
in = new BufferedReader(new InputStreamReader(sock.getInputStream()));
|
||||||
|
//PrintStream out = new PrintStream(sock.getOutputStream());
|
||||||
|
|
||||||
|
// Get the authentication token from the client
|
||||||
|
String authToken = in.readLine();
|
||||||
|
//System.out.println("Token received from client, length = " + authToken.length());
|
||||||
|
|
||||||
|
// Authenticate the token and print out the information available to our service
|
||||||
|
// about the authenticated identity.
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
LoginContext lc = new LoginContext("SampleApp", new SampleAppCallbackHandler(authToken));
|
||||||
|
System.out.println("Authenticating the user");
|
||||||
|
lc.login();
|
||||||
|
|
||||||
|
System.out.println(" Authentication succeeded");
|
||||||
|
|
||||||
|
// Now get the subject associated with the context
|
||||||
|
Subject subject = lc.getSubject();
|
||||||
|
|
||||||
|
// Now get the CasaPrincipals that represent the authenticated
|
||||||
|
// identity or identities.
|
||||||
|
Set principalSet = subject.getPrincipals(CasaPrincipal.class);
|
||||||
|
//System.out.println("The number of CasaPrincipals is: " + principalSet.size());
|
||||||
|
Iterator principalIter = principalSet.iterator();
|
||||||
|
System.out.println();
|
||||||
|
System.out.println("Authenticated Identity Information");
|
||||||
|
System.out.println();
|
||||||
|
while (principalIter.hasNext() == true)
|
||||||
|
{
|
||||||
|
CasaPrincipal principal = (CasaPrincipal) principalIter.next();
|
||||||
|
|
||||||
|
// Print out information about the principal
|
||||||
|
System.out.println(" Source of the identity information: " + principal.getIdentStoreUrl());
|
||||||
|
System.out.println(" Realm name associated with identity source: " + principal.getRealm());
|
||||||
|
System.out.println(" Principal name (unique within identity source realm): " + principal.getName());
|
||||||
|
System.out.println();
|
||||||
|
System.out.println("Authenticated Identity Attributes");
|
||||||
|
System.out.println();
|
||||||
|
javax.naming.directory.Attributes attrs = principal.getAttributes();
|
||||||
|
for (NamingEnumeration ae = attrs.getAll(); ae.hasMore();)
|
||||||
|
{
|
||||||
|
javax.naming.directory.Attribute attr = (javax.naming.directory.Attribute) ae.next();
|
||||||
|
|
||||||
|
NamingEnumeration enumeration = attr.getAll();
|
||||||
|
while (enumeration.hasMore())
|
||||||
|
{
|
||||||
|
System.out.print(" Attribute Name: " + attr.getID());
|
||||||
|
System.out.println(" :: Attribute Value: " + (String) enumeration.next());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
System.out.println();
|
||||||
|
}
|
||||||
|
catch (LoginException e)
|
||||||
|
{
|
||||||
|
System.out.println(" Authentication failed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
if (sock != null)
|
||||||
|
{
|
||||||
|
sock.close();
|
||||||
|
sock = null;
|
||||||
|
}
|
||||||
|
if (in != null)
|
||||||
|
in.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (IOException e)
|
||||||
|
{
|
||||||
|
System.out.println("IOException: " + e.getMessage());
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
System.out.println("Exception: " + e.getMessage());
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (sock != null)
|
||||||
|
{
|
||||||
|
sock.close();
|
||||||
|
}
|
||||||
|
if (listenSock != null)
|
||||||
|
{
|
||||||
|
listenSock.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
System.out.println("Exception: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,71 @@
|
|||||||
|
/***********************************************************************
|
||||||
|
*
|
||||||
|
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; version 2.1
|
||||||
|
* of the License.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Library Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, Novell, Inc.
|
||||||
|
*
|
||||||
|
* To contact Novell about this file by physical or electronic mail,
|
||||||
|
* you may find current contact information at www.novell.com.
|
||||||
|
*
|
||||||
|
* Author: Juan Carlos Luciani <jluciani@novell.com>
|
||||||
|
*
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
package com.novell.casa.jaas;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import javax.security.auth.callback.Callback;
|
||||||
|
import javax.security.auth.callback.CallbackHandler;
|
||||||
|
import javax.security.auth.callback.NameCallback;
|
||||||
|
import javax.security.auth.callback.PasswordCallback;
|
||||||
|
import javax.security.auth.callback.UnsupportedCallbackException;
|
||||||
|
|
||||||
|
|
||||||
|
public class SampleAppCallbackHandler implements CallbackHandler
|
||||||
|
{
|
||||||
|
private String m_authToken;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public SampleAppCallbackHandler(String authToken)
|
||||||
|
{
|
||||||
|
m_authToken = authToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException
|
||||||
|
{
|
||||||
|
for (int i = 0; i < callbacks.length; i++)
|
||||||
|
{
|
||||||
|
if (callbacks[i] instanceof NameCallback) {
|
||||||
|
NameCallback nc = (NameCallback) callbacks[i];
|
||||||
|
nc.setName("CasaIdentityUser");
|
||||||
|
} else if (callbacks[i] instanceof PasswordCallback) {
|
||||||
|
PasswordCallback pc = (PasswordCallback) callbacks[i];
|
||||||
|
//System.out.println("SampleAppCallbackHandler.handle()- Token length = " + m_authToken.length());
|
||||||
|
char[] allChars = m_authToken.toCharArray();
|
||||||
|
|
||||||
|
// Remove the null terminator
|
||||||
|
char[] tokenChars = new char[allChars.length - 1];
|
||||||
|
for (int ii = 0; ii < tokenChars.length; ii++)
|
||||||
|
tokenChars[ii] = allChars[ii];
|
||||||
|
pc.setPassword(tokenChars);
|
||||||
|
} else {
|
||||||
|
throw new UnsupportedCallbackException(callbacks[i], "Unrecognized Callback");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user