diff --git a/auth_token/server/CasaAuthServer/.classpath b/auth_token/server/CasaAuthServer/.classpath new file mode 100644 index 00000000..1efd662b --- /dev/null +++ b/auth_token/server/CasaAuthServer/.classpath @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/auth_token/server/CasaAuthServer/.project b/auth_token/server/CasaAuthServer/.project new file mode 100644 index 00000000..d9faf57a --- /dev/null +++ b/auth_token/server/CasaAuthServer/.project @@ -0,0 +1,35 @@ + + + CasaAuthServer + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.wst.common.project.facet.core.builder + + + + + org.eclipse.wst.validation.validationbuilder + + + + + org.eclipse.jst.j2ee.ejb.annotations.xdoclet.xdocletbuilder + + + + + + org.eclipse.wst.common.project.facet.core.nature + org.eclipse.jdt.core.javanature + org.eclipse.wst.common.modulecore.ModuleCoreNature + org.eclipse.jem.workbench.JavaEMFNature + + diff --git a/auth_token/server/CasaAuthServer/.settings/.component b/auth_token/server/CasaAuthServer/.settings/.component new file mode 100644 index 00000000..4ecbf925 --- /dev/null +++ b/auth_token/server/CasaAuthServer/.settings/.component @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/auth_token/server/CasaAuthServer/.settings/.component-bad b/auth_token/server/CasaAuthServer/.settings/.component-bad new file mode 100644 index 00000000..09fdf0c8 --- /dev/null +++ b/auth_token/server/CasaAuthServer/.settings/.component-bad @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/auth_token/server/CasaAuthServer/.settings/.component-save b/auth_token/server/CasaAuthServer/.settings/.component-save new file mode 100644 index 00000000..092fa05e --- /dev/null +++ b/auth_token/server/CasaAuthServer/.settings/.component-save @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/auth_token/server/CasaAuthServer/.settings/org.eclipse.jdt.core.prefs b/auth_token/server/CasaAuthServer/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 00000000..21779fac --- /dev/null +++ b/auth_token/server/CasaAuthServer/.settings/org.eclipse.jdt.core.prefs @@ -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 diff --git a/auth_token/server/CasaAuthServer/.settings/org.eclipse.jdt.ui.prefs b/auth_token/server/CasaAuthServer/.settings/org.eclipse.jdt.ui.prefs new file mode 100644 index 00000000..ddea6fc6 --- /dev/null +++ b/auth_token/server/CasaAuthServer/.settings/org.eclipse.jdt.ui.prefs @@ -0,0 +1,4 @@ +#Tue Mar 21 11:44:16 MST 2006 +eclipse.preferences.version=1 +formatter_settings_version=8 +internal.default.compliance=default diff --git a/auth_token/server/CasaAuthServer/.settings/org.eclipse.jst.common.project.facet.core.prefs b/auth_token/server/CasaAuthServer/.settings/org.eclipse.jst.common.project.facet.core.prefs new file mode 100644 index 00000000..9bda1236 --- /dev/null +++ b/auth_token/server/CasaAuthServer/.settings/org.eclipse.jst.common.project.facet.core.prefs @@ -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 diff --git a/auth_token/server/CasaAuthServer/.settings/org.eclipse.wst.common.project.facet.core.xml b/auth_token/server/CasaAuthServer/.settings/org.eclipse.wst.common.project.facet.core.xml new file mode 100644 index 00000000..0762753f --- /dev/null +++ b/auth_token/server/CasaAuthServer/.settings/org.eclipse.wst.common.project.facet.core.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/auth_token/server/CasaAuthServer/WebContent/META-INF/MANIFEST.MF b/auth_token/server/CasaAuthServer/WebContent/META-INF/MANIFEST.MF new file mode 100644 index 00000000..5e949512 --- /dev/null +++ b/auth_token/server/CasaAuthServer/WebContent/META-INF/MANIFEST.MF @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +Class-Path: + diff --git a/auth_token/server/CasaAuthServer/WebContent/WEB-INF/web.xml b/auth_token/server/CasaAuthServer/WebContent/WEB-INF/web.xml new file mode 100644 index 00000000..2b57b896 --- /dev/null +++ b/auth_token/server/CasaAuthServer/WebContent/WEB-INF/web.xml @@ -0,0 +1,65 @@ + + + + CasaAuthServer + + + + + GetAuthPolicy + GetAuthPolicy + + com.novell.casa.authserver.GetAuthPolicy + + + + + + PwdAuthenticate + PwdAuthenticate + + com.novell.casa.authserver.PwdAuthenticate + + + + + + Krb5Authenticate + Krb5Authenticate + + com.novell.casa.authserver.Krb5Authenticate + + + + + + GetAuthToken + GetAuthToken + + com.novell.casa.authserver.GetAuthToken + + + GetAuthPolicy + /GetAuthPolicy + + + PwdAuthenticate + /PwdAuthenticate + + + Krb5Authenticate + /Krb5Authenticate + + + GetAuthToken + /GetAuthToken + + + index.html + index.htm + index.jsp + default.html + default.htm + default.jsp + + diff --git a/auth_token/server/CasaAuthServer/src/com/novell/casa/authserver/AuthReqMsg.java b/auth_token/server/CasaAuthServer/src/com/novell/casa/authserver/AuthReqMsg.java new file mode 100644 index 00000000..b106a1db --- /dev/null +++ b/auth_token/server/CasaAuthServer/src/com/novell/casa/authserver/AuthReqMsg.java @@ -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 + * + ***********************************************************************/ + +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: + * + * + * + * realm value + * mechanism token data + * + * + */ +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; + } +} diff --git a/auth_token/server/CasaAuthServer/src/com/novell/casa/authserver/AuthRespMsg.java b/auth_token/server/CasaAuthServer/src/com/novell/casa/authserver/AuthRespMsg.java new file mode 100644 index 00000000..4222c4e8 --- /dev/null +++ b/auth_token/server/CasaAuthServer/src/com/novell/casa/authserver/AuthRespMsg.java @@ -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 + * + ***********************************************************************/ + +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: + * + * + * + * OK200 + * lifetime valuesession token data + * + * + * The format of the message is as follows when the response does not + * include a session token. + * + * + * + * status descriptionstatus code + * + * + * 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 + "" + + statusCode + "" + "\r\n"); + sb.append("" + "\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.httpOkStatusCode + "" + "\r\n"); + sb.append("<" + ProtoDefs.sessionTokenElementName + ">" + + "<" + ProtoDefs.lifetimeElementName + ">" + sessionTokenLifetime + "" + + sessionToken + "" + "\r\n"); + sb.append("" + "\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; + } +} diff --git a/auth_token/server/CasaAuthServer/src/com/novell/casa/authserver/AuthToken.java b/auth_token/server/CasaAuthServer/src/com/novell/casa/authserver/AuthToken.java new file mode 100644 index 00000000..1e1ab5b3 --- /dev/null +++ b/auth_token/server/CasaAuthServer/src/com/novell/casa/authserver/AuthToken.java @@ -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 + * + ***********************************************************************/ + +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: + * + * + * + * signature value + * lifetime value + * Identity Token typeidentity token data + * + * + */ +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 + "" + "\r\n"); + sb.append("<" + ProtoDefs.lifetimeElementName + ">" + m_lifetime + "" + "\r\n"); + sb.append("<" + ProtoDefs.identTokenElementName + " mode=\"escaped\">" + + "<" + ProtoDefs.typeElementName + ">" + m_identityTokenType + "" + + "" + "" + "\r\n"); + sb.append("" + "\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; + } +} diff --git a/auth_token/server/CasaAuthServer/src/com/novell/casa/authserver/Base64Coder.java b/auth_token/server/CasaAuthServer/src/com/novell/casa/authserver/Base64Coder.java new file mode 100644 index 00000000..9573ba44 --- /dev/null +++ b/auth_token/server/CasaAuthServer/src/com/novell/casa/authserver/Base64Coder.java @@ -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. +* +*

+* Copyright 2003: Christian d'Heureuse, Inventec Informatik AG, Switzerland.
+* License: This is "Open Source" software and released under the GNU/LGPL license. +* It is provided "as is" without warranty of any kind. Please contact the author for other licensing arrangements.
+* Home page: www.source-code.biz
+* +*

+* Version history:
+* 2003-07-22 Christian d'Heureuse (chdh): Module created.
+* 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>> 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 + * + ***********************************************************************/ + +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: + * + * + * + * identity id + * identity data source name + * identity data source url + * target service name + * target host name + * + * attribute value + * attribute2 value + * ... + * + * + * + * + * 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 + "\r\n"); + sb.append("<" + sourceNameElementName + ">" + sourceName + "\r\n"); + sb.append("<" + sourceUrlElementName + ">" + m_sourceUrl + "\r\n"); + sb.append("<" + targetServiceElementName + ">" + m_service + "\r\n"); + sb.append("<" + targetHostElementName + ">" + m_host + "\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 + "" + "\r\n"); + } + else + { + sb.append("<" + attr.getID() + ">" + attrValue + "" + "\r\n"); + } + } + } + } + sb.append("" + "\r\n"); + sb.append("" + "\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"); + } + } +} diff --git a/auth_token/server/CasaAuthServer/src/com/novell/casa/authserver/GetAuthPolicy.java b/auth_token/server/CasaAuthServer/src/com/novell/casa/authserver/GetAuthPolicy.java new file mode 100644 index 00000000..6ee066d2 --- /dev/null +++ b/auth_token/server/CasaAuthServer/src/com/novell/casa/authserver/GetAuthPolicy.java @@ -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 + * + ***********************************************************************/ + +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" + "" + "\r\n"); + sb.append("<" + ProtoDefs.mechanismElementName + ">" + "Krb5Authenticate" + "" + "\r\n"); + sb.append("<" + ProtoDefs.mechanismInfoElementName + ">" + "host/jcstation.dnsdhcp.provo.novell.com" + "" + "\r\n"); + sb.append("" + "\r\n"); + sb.append("<" + ProtoDefs.authSourceElementName + ">" + "\r\n"); + sb.append("<" + ProtoDefs.realmElementName + ">" + "jctree" + "" + "\r\n"); + sb.append("<" + ProtoDefs.mechanismElementName + ">" + "PwdAuthenticate" + "" + "\r\n"); + sb.append("<" + ProtoDefs.mechanismInfoElementName + ">" + "" + "" + "\r\n"); + sb.append("" + "\r\n"); + sb.append("" + "\r\n"); + String s = sb.toString(); + return s.getBytes(); + } + } + \ No newline at end of file diff --git a/auth_token/server/CasaAuthServer/src/com/novell/casa/authserver/GetAuthPolicyReqMsg.java b/auth_token/server/CasaAuthServer/src/com/novell/casa/authserver/GetAuthPolicyReqMsg.java new file mode 100644 index 00000000..24014bf5 --- /dev/null +++ b/auth_token/server/CasaAuthServer/src/com/novell/casa/authserver/GetAuthPolicyReqMsg.java @@ -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 + * + ***********************************************************************/ + +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: + * + * + * + * service name + * host name + * + * + */ +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; + } +} diff --git a/auth_token/server/CasaAuthServer/src/com/novell/casa/authserver/GetAuthPolicyRespMsg.java b/auth_token/server/CasaAuthServer/src/com/novell/casa/authserver/GetAuthPolicyRespMsg.java new file mode 100644 index 00000000..09b73688 --- /dev/null +++ b/auth_token/server/CasaAuthServer/src/com/novell/casa/authserver/GetAuthPolicyRespMsg.java @@ -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 + * + ***********************************************************************/ + +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: + * + * + * + * OK200 + * authentication policy data + * + * + * The format of the message is as follows when the response does not + * include an authentication token. + * + * + * + * status descriptionstatus code + * + * + * 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 + "" + + statusCode + "" + "\r\n"); + sb.append("" + "\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.httpOkStatusCode + "" + "\r\n"); + sb.append("<" + ProtoDefs.authPolicyElementName + ">" + authPolicy + "" + "\r\n"); + sb.append("" + "\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; + } +} diff --git a/auth_token/server/CasaAuthServer/src/com/novell/casa/authserver/GetAuthTokReqMsg.java b/auth_token/server/CasaAuthServer/src/com/novell/casa/authserver/GetAuthTokReqMsg.java new file mode 100644 index 00000000..6991d02e --- /dev/null +++ b/auth_token/server/CasaAuthServer/src/com/novell/casa/authserver/GetAuthTokReqMsg.java @@ -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 + * + ***********************************************************************/ + +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: + * + * + * + * service name + * host name + * session token data + * + * + */ +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; + } +} diff --git a/auth_token/server/CasaAuthServer/src/com/novell/casa/authserver/GetAuthTokRespMsg.java b/auth_token/server/CasaAuthServer/src/com/novell/casa/authserver/GetAuthTokRespMsg.java new file mode 100644 index 00000000..da78e433 --- /dev/null +++ b/auth_token/server/CasaAuthServer/src/com/novell/casa/authserver/GetAuthTokRespMsg.java @@ -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 + * + ***********************************************************************/ + +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: + * + * + * + * OK200 + * lifetime valueauthentication token data + * + * + * The format of the message is as follows when the response does not + * include an authentication token. + * + * + * + * status descriptionstatus code + * + * + * 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 + "" + + statusCode + "" + "\r\n"); + sb.append("" + "\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.httpOkStatusCode + "" + "\r\n"); + sb.append("<" + ProtoDefs.authTokenElementName + ">" + + "<" + ProtoDefs.lifetimeElementName + ">" + authTokenLifetime + "" + + authToken + "" + "\r\n"); + sb.append("" + "\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; + } +} + diff --git a/auth_token/server/CasaAuthServer/src/com/novell/casa/authserver/GetAuthToken.java b/auth_token/server/CasaAuthServer/src/com/novell/casa/authserver/GetAuthToken.java new file mode 100644 index 00000000..e9a59962 --- /dev/null +++ b/auth_token/server/CasaAuthServer/src/com/novell/casa/authserver/GetAuthToken.java @@ -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 + * + ***********************************************************************/ + +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(); + } +} \ No newline at end of file diff --git a/auth_token/server/CasaAuthServer/src/com/novell/casa/authserver/IdentityToken.java b/auth_token/server/CasaAuthServer/src/com/novell/casa/authserver/IdentityToken.java new file mode 100644 index 00000000..e9c5d49b --- /dev/null +++ b/auth_token/server/CasaAuthServer/src/com/novell/casa/authserver/IdentityToken.java @@ -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 + * + ***********************************************************************/ + +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; +} diff --git a/auth_token/server/CasaAuthServer/src/com/novell/casa/authserver/Krb5Authenticate.java b/auth_token/server/CasaAuthServer/src/com/novell/casa/authserver/Krb5Authenticate.java new file mode 100644 index 00000000..c6dde7d8 --- /dev/null +++ b/auth_token/server/CasaAuthServer/src/com/novell/casa/authserver/Krb5Authenticate.java @@ -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 + * + ***********************************************************************/ + +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(); + } +} \ No newline at end of file diff --git a/auth_token/server/CasaAuthServer/src/com/novell/casa/authserver/ProtoDefs.java b/auth_token/server/CasaAuthServer/src/com/novell/casa/authserver/ProtoDefs.java new file mode 100644 index 00000000..c5786e21 --- /dev/null +++ b/auth_token/server/CasaAuthServer/src/com/novell/casa/authserver/ProtoDefs.java @@ -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 + * + ***********************************************************************/ + +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 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"; +} diff --git a/auth_token/server/CasaAuthServer/src/com/novell/casa/authserver/PwdAuthenticate.java b/auth_token/server/CasaAuthServer/src/com/novell/casa/authserver/PwdAuthenticate.java new file mode 100644 index 00000000..d0fa2c4f --- /dev/null +++ b/auth_token/server/CasaAuthServer/src/com/novell/casa/authserver/PwdAuthenticate.java @@ -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 + * + ***********************************************************************/ + +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(); + } +} \ No newline at end of file diff --git a/auth_token/server/CasaAuthServer/src/com/novell/casa/authserver/SessionToken.java b/auth_token/server/CasaAuthServer/src/com/novell/casa/authserver/SessionToken.java new file mode 100644 index 00000000..b570cdd4 --- /dev/null +++ b/auth_token/server/CasaAuthServer/src/com/novell/casa/authserver/SessionToken.java @@ -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 + * + ***********************************************************************/ + +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: +* +* +* +* signature value +* lifetime value +* realm value +* identity id value +* +* +*/ +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 + "" + "\r\n"); + sb.append("<" + ProtoDefs.lifetimeElementName + ">" + m_lifetime + "" + "\r\n"); + sb.append("<" + ProtoDefs.realmElementName + ">" + m_realm + "" + "\r\n"); + sb.append("<" + ProtoDefs.identIdElementName + ">" + m_id + "" + "\r\n"); + sb.append("" + "\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; + } +} diff --git a/auth_token/server/CasaJaasSupport/.classpath b/auth_token/server/CasaJaasSupport/.classpath new file mode 100644 index 00000000..60dd0413 --- /dev/null +++ b/auth_token/server/CasaJaasSupport/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/auth_token/server/CasaJaasSupport/.project b/auth_token/server/CasaJaasSupport/.project new file mode 100644 index 00000000..cdeff8ac --- /dev/null +++ b/auth_token/server/CasaJaasSupport/.project @@ -0,0 +1,17 @@ + + + CasaJaasSupport + + + + + + org.eclipse.jdt.core.javabuilder + + + + + + org.eclipse.jdt.core.javanature + + diff --git a/auth_token/server/CasaJaasSupport/src/com/novell/casa/jaas/CasaLoginModule.java b/auth_token/server/CasaJaasSupport/src/com/novell/casa/jaas/CasaLoginModule.java new file mode 100644 index 00000000..7883d669 --- /dev/null +++ b/auth_token/server/CasaJaasSupport/src/com/novell/casa/jaas/CasaLoginModule.java @@ -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 + * + ***********************************************************************/ + +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; + } +} diff --git a/auth_token/server/CasaJaasSupport/src/com/novell/casa/jaas/CasaPrincipal.java b/auth_token/server/CasaJaasSupport/src/com/novell/casa/jaas/CasaPrincipal.java new file mode 100644 index 00000000..1c74dea6 --- /dev/null +++ b/auth_token/server/CasaJaasSupport/src/com/novell/casa/jaas/CasaPrincipal.java @@ -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; + } +} diff --git a/auth_token/server/CasaJaasSupport/src/com/novell/casa/jaas/SampleApp.conf b/auth_token/server/CasaJaasSupport/src/com/novell/casa/jaas/SampleApp.conf new file mode 100644 index 00000000..a1c76192 --- /dev/null +++ b/auth_token/server/CasaJaasSupport/src/com/novell/casa/jaas/SampleApp.conf @@ -0,0 +1,3 @@ +SampleApp { + com.novell.casa.jaas.CasaLoginModule Required debug=true; +}; \ No newline at end of file diff --git a/auth_token/server/CasaJaasSupport/src/com/novell/casa/jaas/SampleApp.java b/auth_token/server/CasaJaasSupport/src/com/novell/casa/jaas/SampleApp.java new file mode 100644 index 00000000..29e602ff --- /dev/null +++ b/auth_token/server/CasaJaasSupport/src/com/novell/casa/jaas/SampleApp.java @@ -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 + * + ***********************************************************************/ + +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()); + } + } + } +} diff --git a/auth_token/server/CasaJaasSupport/src/com/novell/casa/jaas/SampleAppCallbackHandler.java b/auth_token/server/CasaJaasSupport/src/com/novell/casa/jaas/SampleAppCallbackHandler.java new file mode 100644 index 00000000..a8b1304e --- /dev/null +++ b/auth_token/server/CasaJaasSupport/src/com/novell/casa/jaas/SampleAppCallbackHandler.java @@ -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 + * + ***********************************************************************/ + +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"); + } + } + } +}