[Feat] - Toutes les notes de SSI sur la gestion d'un policyFile (sans policytool) et la signature avec et sans certification + fichier revision by lucas

This commit is contained in:
kmitresse
2024-11-08 08:56:46 +01:00
parent a2e042a9a3
commit c84ebb90b1
49 changed files with 2967 additions and 0 deletions
+20
View File
@@ -0,0 +1,20 @@
-----BEGIN CERTIFICATE-----
MIIDRTCCAi2gAwIBAgIUeFkqQDxs67AqhUPln8Yzm44H2zkwDQYJKoZIhvcNAQEL
BQAwMjEUMBIGA1UEAwwLU2ltdWxhdGVkQ0ExDTALBgNVBAoMBE15Q0ExCzAJBgNV
BAYTAkZSMB4XDTI0MTEwNzIxMzk1NloXDTI1MTEwNzIxMzk1NlowMjEUMBIGA1UE
AwwLU2ltdWxhdGVkQ0ExDTALBgNVBAoMBE15Q0ExCzAJBgNVBAYTAkZSMIIBIjAN
BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2kK6igwUFT7qLOwhrVva+yir/OF+
p56T7kyXrp7UZwtIta7O5VT3BhhC8C1jVbK9hpTJ7FoSesksF+xwdapLiXBEj/B2
COvNBFf432iGx+6fCAhkA95D8/zIxBf+QgbL5EgWPXn/emsZMomPH6wmwI20HTvL
ANbqfLe4vvU3KR+GcnfC24rQsoXgfZIHBKaa3Vrc005J+JhoCTY4NK3AAy/ngMm9
dsmVgaPrBzzm6XYliqp8ma7xZTTjRIIKyow4aPVG1BQZW3Tayx30+8L6HR3niCDr
5MlNIP94hCC14i47UPRdOQQX4etSd8C9LbWHUkiSkf5Dmj84qqY3DihifQIDAQAB
o1MwUTAdBgNVHQ4EFgQU7uGkETin7lsxsjUOS3Udk6qZV60wHwYDVR0jBBgwFoAU
7uGkETin7lsxsjUOS3Udk6qZV60wDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0B
AQsFAAOCAQEACfi9sjsMMNWPTlvF8ycvVQ0Kn8yhx6deQL5NYSPc48BD0miaPhvL
jaumUzbzNxkI0XiyKBpXKOLjLt3zyBQh2tpBW5oqJ5q0L6oiOtswvZpXklyYN2RR
RX3M0WFDcQD7uRxSXznKzwkFqxbY+kNMWEfYtIzCEFJ8BYkKBSTR8S6MYbCSlheK
PbW+U3+1LMcYuERMfSywD2C+nzb9Xz1LSZCVkaltEknvMj/tzUcytxxjRs2RqSsr
phyTjAE2HxpN/buQ9WmIrUbBBRrRKAVl+Vv1JB5A8R/gzeNe3nbv1zkGak0M2ddn
Dy4VDMgwwSee/X8F/tG29R9hEI//d2kR3w==
-----END CERTIFICATE-----
+28
View File
@@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDaQrqKDBQVPuos
7CGtW9r7KKv84X6nnpPuTJeuntRnC0i1rs7lVPcGGELwLWNVsr2GlMnsWhJ6ySwX
7HB1qkuJcESP8HYI680EV/jfaIbH7p8ICGQD3kPz/MjEF/5CBsvkSBY9ef96axky
iY8frCbAjbQdO8sA1up8t7i+9TcpH4Zyd8LbitCyheB9kgcEpprdWtzTTkn4mGgJ
Njg0rcADL+eAyb12yZWBo+sHPObpdiWKqnyZrvFlNONEggrKjDho9UbUFBlbdNrL
HfT7wvodHeeIIOvkyU0g/3iEILXiLjtQ9F05BBfh61J3wL0ttYdSSJKR/kOaPziq
pjcOKGJ9AgMBAAECggEABsISrxQVKhw+2YG9QDYsJ2M4whWEW7HSEEqgVriVyJQF
nhSJ1PmGxZJKPlAVd5GXgzuHrhES6ejhO+NnDwmlGZ4XjWJrcTbF7BjCPL6qj7XA
iFnkKOeAsKUW3VWF2qsFtK2TvLcSlUqMJu+x9g/ZSlSI62/OxxmgfJieuJD0son3
9ln6+95UZfpmlOSFb5G1+oDAX1b+S2ykdSG8Daqibh6egFn9WZ9CLmhVhkwnWPli
r+EXZdYHxulU+454lz1jUT3ooWehp1Lkurlysr4Q3B52Zwsdg9pum8kCewLlz3la
agGYdXoW9sW3AWN+J3+n5oOsXr3/aZ+CV8GobRgbwQKBgQDnwLYiOOrEFaLxMR0/
CrW9smoL6IMRPRt7CpG6ePvKoaEaJMfBfutgUmbh2vp6KMAilkaZ7sBPxSY5Td+p
Cv4IxJ/dplMqknnujhC3vQJkdrrown//4PuNGKq7P0q/CY2KTTTj1liM0JorhPr5
8ycUj7gxclj72PyqJfeBJKRvQQKBgQDxGKSZ35z000jcRnt9L8JOhcZZX7GAJX9m
ktGhmu8pvCGBUryKwva8+Ct6MO+uLfadNXN2T0okfKAiTDx+O5GFobgMcmFk/3ki
WBbub/Nxk+1qgfG3gb6dyRzJoSIvMMoVnAQLNiGZp+xp9IHixMBrGy21kEFwzZn8
hgHKymHgPQKBgDagnk4CzJPb5cSkpxgtFhnY7FZSQFLX7JpcK22hBvkEkEzxToS1
vhW+VrH2RAR3hpKgiZPPS1WCSzhGuunFxYubjXNZuVDXphYtNpOY4e98bSJgdnuC
NMlVfykUCjJttgdbm5P4+nZ21WBcwCwavKOEHQ7KvV7gDu6sdGLkmD4BAoGAULz6
6li7HDXhUXr9AchLnrYn3WgxbgOgrX3/W8ohy20oH0HQx/tQW6oUDUB0E3Vq/+yV
dQpKfvuJONMk8vUJ36FvnCN1wDfZngm37DNraB6sxB0uEFEPv5FI5bDjXMBO/HuZ
0xNWnzlf73+lO4a+FWAtp37em2MO7UUHNp0dt9UCgYBTbDhzIV7aDluEUqJbBa2Y
CBvkJ/9+utAL9eyf30y+Hh3ZWKxc5kuRK6xlJyxamZmFqpaGLsmN+KaWEgUojrXv
j7Es/ry5W6mDiIIbCSULu1e/7cdUsno/HhdSxVyWKAuOjFtLEWC4pXGiD6Vpgpoo
wVO01w/kd7bhhkAqskuGxQ==
-----END PRIVATE KEY-----
@@ -0,0 +1 @@
Main-Class: Source
+5
View File
@@ -0,0 +1,5 @@
public class Source {
public static void main(String[] args) {
System.out.println("Hello world!");
}
}
Binary file not shown.
@@ -0,0 +1,18 @@
-----BEGIN NEW CERTIFICATE REQUEST-----
MIIC6zCCAdMCAQAwdjELMAkGA1UEBhMCRlIxFDASBgNVBAgTC0NsaWVudFN0YXRl
MRMwEQYDVQQHEwpDbGllbnRDaXR5MRIwEAYDVQQKEwlDbGllbnRPcmcxEzARBgNV
BAsTCkNsaWVudFVuaXQxEzARBgNVBAMTCkNsaWVudE5hbWUwggEiMA0GCSqGSIb3
DQEBAQUAA4IBDwAwggEKAoIBAQC75nji+y18JE4ts5WI0MiZTN+Pq6P6jGbbm2lC
LhK1J/YDuB2jWENaTBv47zfEbI9JPE/f0I65EqOHq2mFJPWVA3S/m5fdZmPSfSew
a45eTFH0UwBHEI3jvUWO3Vm4KXTZoaRHt15dAg4ltY39OhpnGAzAvS4IovY3FS/i
voTz/O2kgUA1VHESJGmpIsCOPsTB6KBozZ36S75d3QDKG6y2NvlYMY3NkOn/w+pv
ZWXM1W1H5cbyU/B/mX6bUJ6Eogz5XjzyakZJKqGzt9IfGK7dHUG6l6PFms6Inwj4
SPhVUlcHG9x50Sm7KBctHcUhZ6OnIlRWjZ5J/775HuExte/nAgMBAAGgMDAuBgkq
hkiG9w0BCQ4xITAfMB0GA1UdDgQWBBRWo1xWegFOkWheOw+c0fNeJpliKzANBgkq
hkiG9w0BAQwFAAOCAQEAVP8BdkzGCawgryXMrZTBT1ZTNofcM5Yqtl6KqaXbSO0c
7VxkdrgjRZCODZ0v1WW1aQxqfdDxqp5LgxdU8cDPs9FtayIy3GhDF076ZLDWJU89
hDgGmY20/VfdA+eGFduvQ9QsLF2idin64mKCri0JcpSv+Wb9EAjL/JnS7FtyarSI
EgYb0IY+K1PFFXGz7ScP6e0nPIlwgCM/1AmhKZPQidMS5aEZ77tXqN+X4eK7j+u5
KediiE0KKdYMn9Dmvu8cAr1U6MryATqp17TUCY9nRpqabA22rBGUAcYuutAoO01J
HcvvQbYyiG0qu2uI/DZ459/1MitAy+zyLF5EBk10dQ==
-----END NEW CERTIFICATE REQUEST-----
@@ -0,0 +1,20 @@
-----BEGIN CERTIFICATE-----
MIIDLzCCAhcCFG7u2CvIlzwV1EvzuwFNZqJ0a/XuMA0GCSqGSIb3DQEBCwUAMDIx
FDASBgNVBAMMC1NpbXVsYXRlZENBMQ0wCwYDVQQKDARNeUNBMQswCQYDVQQGEwJG
UjAeFw0yNDExMDcyMTM5NThaFw0yNTExMDcyMTM5NThaMHYxCzAJBgNVBAYTAkZS
MRQwEgYDVQQIEwtDbGllbnRTdGF0ZTETMBEGA1UEBxMKQ2xpZW50Q2l0eTESMBAG
A1UEChMJQ2xpZW50T3JnMRMwEQYDVQQLEwpDbGllbnRVbml0MRMwEQYDVQQDEwpD
bGllbnROYW1lMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu+Z44vst
fCROLbOViNDImUzfj6uj+oxm25tpQi4StSf2A7gdo1hDWkwb+O83xGyPSTxP39CO
uRKjh6tphST1lQN0v5uX3WZj0n0nsGuOXkxR9FMARxCN471Fjt1ZuCl02aGkR7de
XQIOJbWN/ToaZxgMwL0uCKL2NxUv4r6E8/ztpIFANVRxEiRpqSLAjj7EweigaM2d
+ku+Xd0Ayhustjb5WDGNzZDp/8Pqb2VlzNVtR+XG8lPwf5l+m1CehKIM+V488mpG
SSqhs7fSHxiu3R1BupejxZrOiJ8I+Ej4VVJXBxvcedEpuygXLR3FIWejpyJUVo2e
Sf+++R7hMbXv5wIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQAEDpr35o67ao21lZZO
DlidqPbZ6y9FsowzbXZMHqNYjkeBTjmVOIkm8jLj9ZWqrAM4WPARSpRzRzyplQcO
0KuQtJQzgdwd5YTc3FCSRuV8ZTu9qrdY5N3/TA+xOpTuOHj/05oF8ngqXRDACMO8
e0MUMNWNxeX03iK4fdzaVZuKcALrjgNIpZ+SugvOILP8fUrJN2iLLtP18ccG8My+
LlIi3H70yx9EfsEEca2P2RRJ//7PSIW1vciEK7Qd0iKVHUmSPCBvtbaWMXKoYK8L
hubTjIAtt8I+N5mbEl7bxzLFnTzGJxIH3mZwPWTGC6Owt8Bsgwu5KCIR7yIwep6C
PIGK
-----END CERTIFICATE-----
Binary file not shown.
+9
View File
@@ -0,0 +1,9 @@
keystore "./client/keystore.jks"
grant signedBy "KeyAlias" {
permission java.io.FilePermission "${user.home}${/}PauUniversty/Master-TI-2/security/Notes/Example/Client/Source_Signed.jar", "read, execute";
};
grant codeBase "file:/home/kmitresse/PauUniversity/Master-TI-2/security/Notes/" {
permission java.util.PropertyPermission "user.home", "read";
};
@@ -0,0 +1,3 @@
grant codeBase "file:./" {
};
@@ -0,0 +1,4 @@
grant codeBase "file:${user.home}${/}Documents${/}Github${/}SecuriteSystemesInfo${/}revision${/}tp1${/}partie2${/}" {
permission "java.util.PropertyPermission" "user.home", "read";
permission "java.util.PropertyPermission" "java.home", "read";
};
@@ -0,0 +1,28 @@
import java.lang.*;
class GetProps {
public static void main(String[] args) {
try {
final String OS_NAME = GetProps.getProperty("os.name");
final String JAVA_VERSION = GetProps.getProperty("java.version");
final String USER_HOME = GetProps.getProperty("user.home");
final String JAVA_HOME = GetProps.getProperty("java.home");
System.out.println(
"os.name : " + OS_NAME + "\n"
+ "java.version : " + JAVA_VERSION + "\n"
+ "user.home : " + USER_HOME + "\n"
+ "java.home : " + JAVA_HOME
);
} catch (Exception e) {
System.err.println("Caught exception " + e.toString());
}
}
private static String getProperty(String property_name) {
final String DEFAULT_VALUE = "not specified";
return System.getProperty(property_name, DEFAULT_VALUE);
}
}
@@ -0,0 +1,10 @@
# Compile Java file
javac ./GetProps.java
# Execute with security manager and policy file
java -Djava.security.manager \
-Djava.security.policy=.policy \
GetProps
# Remove compiled file
rm ./GetProps.class
@@ -0,0 +1,5 @@
public class Source {
public static void main(String[] args) {
System.out.println("Hello world!");
}
}
@@ -0,0 +1,29 @@
# Reset
rm ./keystore.jks ./Source_Signed.jar
# Génère un keystore
keytool -genkeypair \
-alias SourceKeyAlias \
-keyalg RSA \
-keysize 2048 \
-keystore keystore.jks \
-validity 365
# Compilation
javac ./Source.java
# Créer un fichier MANIFEST.MF avec l'attribut Main-Class
echo "Main-Class: Source" > MANIFEST.MF
# Crée le fichier JAR non signé avec le MANIFEST.MF modifié
jar cmf MANIFEST.MF Source.jar Source.class
# Convertir en fichier JAR signé
jarsigner -keystore keystore.jks \
-signedjar Source_Signed.jar Source.jar SourceKeyAlias
# Supprime les artéfacts
rm ./Source.class ./Source.jar MANIFEST.MF
# Essaye d'exécuter ton fichier JAR signé
java -jar Source_Signed.jar
@@ -0,0 +1,5 @@
public class Source {
public static void main(String[] args) {
System.out.println("Hello world!");
}
}
@@ -0,0 +1,112 @@
#!/bin/bash
# Reset
rm -rf ./CA
rm ./client/certificat_request.csr \
./client/certificat_signed.cer \
./client/certificat.cer \
./client/keystore.jks \
./client/Source_Signed.jar
##########################################
# Création des dossiers CA et client s'ils n'existent pas déjà
mkdir -p CA client
# Génération de la clé privée de la CA
openssl genrsa -out CA/ca.key 2048
echo "[CA] - génération de la clé privée : OK"
# Génération du certificat auto-signé de la CA
openssl req -x509 -new -nodes \
-key CA/ca.key -sha256 -days 365 \
-out CA/ca.crt \
-subj "/CN=SimulatedCA/O=MyCA/C=FR"
echo "[CA] - génération du certificat auto-signé : OK"
# Génération du keystore du client
keytool -genkeypair \
-alias KeyAlias \
-keyalg RSA \
-keysize 2048 \
-keystore client/keystore.jks \
-validity 365 \
-dname "CN=ClientName, OU=ClientUnit, O=ClientOrg, L=ClientCity, S=ClientState, C=FR" \
-storepass changeit \
-keypass changeit
echo "[Client] - Génération du keystore : OK"
# Génération de la demande de certificat (CSR) pour le client
keytool -certreq \
-alias KeyAlias \
-keystore client/keystore.jks \
-file client/certificat_request.csr \
-storepass changeit
echo "[Client] - Génération de la demande de certification : OK"
# La CA signe la demande de certificat du client
openssl x509 -req \
-in client/certificat_request.csr \
-CA CA/ca.crt -CAkey CA/ca.key -CAcreateserial \
-out client/certificat_signed.cer -days 365 -sha256
echo "[CA] - Signature de la demande de certificat : OK"
# Importation du certificat de la CA dans le keystore du client
keytool -import \
-trustcacerts \
-alias SimulatedCA \
-file CA/ca.crt \
-keystore client/keystore.jks \
-noprompt \
-storepass changeit
echo "[Client] - Import du certificat du CA : OK"
# Importation du certificat signé dans le keystore du client
keytool -import \
-alias KeyAlias \
-keystore client/keystore.jks \
-file client/certificat_signed.cer \
-noprompt \
-storepass changeit
echo "[Client] - Import du certificat signé : OK"
# Exportation du certificat signé pour distribution
keytool -export \
-alias KeyAlias \
-keystore client/keystore.jks \
-file client/certificat.cer \
-storepass changeit
echo "[Client] - Export du certificat signé : OK"
##########################################
cd ./client/
# Compile notre fichier java
javac ./Source.java
echo "[Client] - Compilation du .java : OK"
# Créer un fichier MANIFEST.MF avec l'attribut Main-Class
echo "Main-Class: Source" > ./MANIFEST.MF
# Créé le fichier Jar non signé
jar cmf ./MANIFEST.MF ./Source.jar ./Source.class
echo "[Client] - Creation du fichier .jar : OK"
# Convertis en fichier jar signé
jarsigner -keystore ./keystore.jks \
-storepass changeit \
-signedjar ./Source_Signed.jar ./Source.jar KeyAlias
echo "[Client] - Creation du fichier .jar signé : OK"
# Supprime les artéfacts
rm ./Source.class ./Source.jar ./MANIFEST.MF
# On peut vérifier que notre certificat est bien valide
jarsigner -verify ./Source_Signed.jar
echo "[Client] - Vérification du certificat : OK"
cd ..
# Executer le jar signé
java -jar ./client/Source_Signed.jar
@@ -0,0 +1,10 @@
keystore "keystore.jks";
grant signedBy "KeyAlias" {
permission java.io.FilePermission "${user.home}${/}Documents${/}Github${/}SecuriteSystemesInfo${/}revision${/}tp1${/}partie5${/}client${/}Source_Signed.jar", "read, execute";
};
grant codeBase "file:${user.home}${/}Documents${/}Github${/}SecuriteSystemesInfo${/}revision${/}tp1${/}partie5${/}client${/}Source_Signed.jar" {
permission "java.util.PropertyPermission" "user.home", "read";
permission "java.util.PropertyPermission" "java.home", "read";
};
@@ -0,0 +1,27 @@
import java.lang.*;
public class Source {
public static void main(String[] args) {
try {
final String OS_NAME = Source.getProperty("os.name");
final String JAVA_VERSION = Source.getProperty("java.version");
final String USER_HOME = Source.getProperty("user.home");
final String JAVA_HOME = Source.getProperty("java.home");
System.out.println(
"os.name : " + OS_NAME + "\n"
+ "java.version : " + JAVA_VERSION + "\n"
+ "user.home : " + USER_HOME + "\n"
+ "java.home : " + JAVA_HOME
);
} catch (Exception e) {
System.err.println("Caught exception " + e.toString());
}
}
private static String getProperty(String property_name) {
final String DEFAULT_VALUE = "not specified";
return System.getProperty(property_name, DEFAULT_VALUE);
}
}
@@ -0,0 +1,114 @@
#!/bin/bash
# Reset
rm -rf ./CA
rm ./client/certificat_request.csr \
./client/certificat_signed.cer \
./client/certificat.cer \
./client/keystore.jks \
./client/Source_Signed.jar
##########################################
# Création des dossiers CA et client s'ils n'existent pas déjà
mkdir -p CA client
# Génération de la clé privée de la CA
openssl genrsa -out CA/ca.key 2048
echo "[CA] - génération de la clé privée : OK"
# Génération du certificat auto-signé de la CA
openssl req -x509 -new -nodes \
-key CA/ca.key -sha256 -days 365 \
-out CA/ca.crt \
-subj "/CN=SimulatedCA/O=MyCA/C=FR"
echo "[CA] - génération du certificat auto-signé : OK"
# Génération du keystore du client
keytool -genkeypair \
-alias KeyAlias \
-keyalg RSA \
-keysize 2048 \
-keystore client/keystore.jks \
-validity 365 \
-dname "CN=ClientName, OU=ClientUnit, O=ClientOrg, L=ClientCity, S=ClientState, C=FR" \
-storepass changeit \
-keypass changeit
echo "[Client] - Génération du keystore : OK"
# Génération de la demande de certificat (CSR) pour le client
keytool -certreq \
-alias KeyAlias \
-keystore client/keystore.jks \
-file client/certificat_request.csr \
-storepass changeit
echo "[Client] - Génération de la demande de certification : OK"
# La CA signe la demande de certificat du client
openssl x509 -req \
-in client/certificat_request.csr \
-CA CA/ca.crt -CAkey CA/ca.key -CAcreateserial \
-out client/certificat_signed.cer -days 365 -sha256
echo "[CA] - Signature de la demande de certificat : OK"
# Importation du certificat de la CA dans le keystore du client
keytool -import \
-trustcacerts \
-alias SimulatedCA \
-file CA/ca.crt \
-keystore client/keystore.jks \
-noprompt \
-storepass changeit
echo "[Client] - Import du certificat du CA : OK"
# Importation du certificat signé dans le keystore du client
keytool -import \
-alias KeyAlias \
-keystore client/keystore.jks \
-file client/certificat_signed.cer \
-noprompt \
-storepass changeit
echo "[Client] - Import du certificat signé : OK"
# Exportation du certificat signé pour distribution
keytool -export \
-alias KeyAlias \
-keystore client/keystore.jks \
-file client/certificat.cer \
-storepass changeit
echo "[Client] - Export du certificat signé : OK"
##########################################
cd client
# Compile notre fichier java
javac Source.java
echo "[Client] - Compilation du .java : OK"
# Créer un fichier MANIFEST.MF avec l'attribut Main-Class
echo "Main-Class: Source" > MANIFEST.MF
# Créé le fichier Jar non signé
jar cmf MANIFEST.MF Source.jar Source.class
echo "[Client] - Creation du fichier .jar : OK"
# Convertis en fichier jar signé
jarsigner -keystore keystore.jks \
-storepass changeit \
-signedjar Source_Signed.jar Source.jar KeyAlias
echo "[Client] - Creation du fichier .jar signé : OK"
# Supprime les artéfacts
rm Source.class Source.jar MANIFEST.MF
# On peut vérifier que notre certificat est bien valide
jarsigner -verify Source_Signed.jar
echo "[Client] - Vérification du certificat : OK"
# Executer le jar signé
java -Djava.security.manager \
-Djava.security.policy=.policy \
-jar Source_Signed.jar
cd ..
@@ -0,0 +1,5 @@
/** Login Configuration for the JAAS Sample Application **/
Sample {
sample.module.SampleLoginModule required debug=true;
};
@@ -0,0 +1,15 @@
# Compile Java files
javac \
sample/SampleAcn.java \
sample/module/SampleLoginModule.java \
sample/principal/SamplePrincipal.java
# Execute
java -Djava.security.auth.login.config==jaas.config sample.SampleAcn
# Reset
rm \
./sample/MyCallbackHandler.class \
./sample/SampleAcn.class \
./sample/module/SampleLoginModule.class \
./sample/principal/SamplePrincipal.class
@@ -0,0 +1,240 @@
/*
*
* Copyright (c) 2001, 2002, Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* -Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* -Redistribution in binary form must reproduct the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* Neither the name of Oracle nor the names of
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* This software is provided "AS IS," without a warranty of any
* kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
* WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
* EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY
* DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT OF OR
* RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR
* ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE
* FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT,
* SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
* CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF
* THE USE OF OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
*
* You acknowledge that Software is not designed, licensed or
* intended for use in the design, construction, operation or
* maintenance of any nuclear facility.
*/
package sample;
import java.io.*;
import java.util.*;
import javax.security.auth.login.*;
import javax.security.auth.*;
import javax.security.auth.callback.*;
/**
* <p> This Sample application attempts to authenticate a user
* and reports whether or not the authentication was successful.
*/
public class SampleAcn {
/**
* Attempt to authenticate the user.
*
* <p>
*
* @param args input arguments for this application. These are ignored.
*/
public static void main(String[] args) {
// Obtain a LoginContext, needed for authentication. Tell it
// to use the LoginModule implementation specified by the
// entry named "Sample" in the JAAS login configuration
// file and to also use the specified CallbackHandler.
LoginContext lc = null;
try {
lc = new LoginContext("Sample", new MyCallbackHandler());
} catch (LoginException le) {
System.err.println("Cannot create LoginContext. "
+ le.getMessage());
System.exit(-1);
} catch (SecurityException se) {
System.err.println("Cannot create LoginContext. "
+ se.getMessage());
System.exit(-1);
}
// the user has 3 attempts to authenticate successfully
int i;
for (i = 0; i < 3; i++) {
try {
// attempt authentication
lc.login();
// if we return with no exception, authentication succeeded
break;
} catch (LoginException le) {
System.err.println("Authentication failed:");
System.err.println(" " + le.getMessage());
try {
Thread.currentThread().sleep(3000);
} catch (Exception e) {
// ignore
}
}
}
// did they fail three times?
if (i == 3) {
System.out.println("Sorry");
System.exit(-1);
}
System.out.println("Authentication succeeded!");
}
}
/**
* The application implements the CallbackHandler.
*
* <p> This application is text-based. Therefore it displays information
* to the user using the OutputStreams System.out and System.err,
* and gathers input from the user using the InputStream System.in.
*/
class MyCallbackHandler implements CallbackHandler {
/**
* Invoke an array of Callbacks.
*
* <p>
*
* @param callbacks an array of <code>Callback</code> objects which contain
* the information requested by an underlying security
* service to be retrieved or displayed.
*
* @exception java.io.IOException if an input or output error occurs. <p>
*
* @exception UnsupportedCallbackException if the implementation of this
* method does not support one or more of the Callbacks
* specified in the <code>callbacks</code> parameter.
*/
public void handle(Callback[] callbacks)
throws IOException, UnsupportedCallbackException {
for (int i = 0; i < callbacks.length; i++) {
if (callbacks[i] instanceof TextOutputCallback) {
// display the message according to the specified type
TextOutputCallback toc = (TextOutputCallback)callbacks[i];
switch (toc.getMessageType()) {
case TextOutputCallback.INFORMATION:
System.out.println(toc.getMessage());
break;
case TextOutputCallback.ERROR:
System.out.println("ERROR: " + toc.getMessage());
break;
case TextOutputCallback.WARNING:
System.out.println("WARNING: " + toc.getMessage());
break;
default:
throw new IOException("Unsupported message type: " +
toc.getMessageType());
}
} else if (callbacks[i] instanceof NameCallback) {
// prompt the user for a username
NameCallback nc = (NameCallback)callbacks[i];
System.err.print(nc.getPrompt());
System.err.flush();
nc.setName((new BufferedReader
(new InputStreamReader(System.in))).readLine());
} else if (callbacks[i] instanceof PasswordCallback) {
// prompt the user for sensitive information
PasswordCallback pc = (PasswordCallback)callbacks[i];
System.err.print(pc.getPrompt());
System.err.flush();
pc.setPassword(readPassword(System.in));
} else {
throw new UnsupportedCallbackException
(callbacks[i], "Unrecognized Callback");
}
}
}
// Reads user password from given input stream.
private char[] readPassword(InputStream in) throws IOException {
char[] lineBuffer;
char[] buf;
int i;
buf = lineBuffer = new char[128];
int room = buf.length;
int offset = 0;
int c;
loop: while (true) {
switch (c = in.read()) {
case -1:
case '\n':
break loop;
case '\r':
int c2 = in.read();
if ((c2 != '\n') && (c2 != -1)) {
if (!(in instanceof PushbackInputStream)) {
in = new PushbackInputStream(in);
}
((PushbackInputStream)in).unread(c2);
} else
break loop;
default:
if (--room < 0) {
buf = new char[offset + 128];
room = buf.length - offset - 1;
System.arraycopy(lineBuffer, 0, buf, 0, offset);
Arrays.fill(lineBuffer, ' ');
lineBuffer = buf;
}
buf[offset++] = (char) c;
break;
}
}
if (offset == 0) {
return null;
}
char[] ret = new char[offset];
System.arraycopy(buf, 0, ret, 0, offset);
Arrays.fill(buf, ' ');
return ret;
}
}
@@ -0,0 +1,337 @@
/*
*
* Copyright (c) 2000, 2002, Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* -Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* -Redistribution in binary form must reproduct the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* Neither the name of Oracle nor the names of
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* This software is provided "AS IS," without a warranty of any
* kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
* WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
* EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY
* DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT OF OR
* RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR
* ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE
* FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT,
* SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
* CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF
* THE USE OF OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
*
* You acknowledge that Software is not designed, licensed or
* intended for use in the design, construction, operation or
* maintenance of any nuclear facility.
*/
package sample.module;
import java.util.*;
import java.io.IOException;
import javax.security.auth.*;
import javax.security.auth.callback.*;
import javax.security.auth.login.*;
import javax.security.auth.spi.*;
import sample.principal.SamplePrincipal;
/**
* <p> This sample LoginModule authenticates users with a password.
*
* <p> This LoginModule only recognizes one user: testUser
* <p> testUser's password is: testPassword
*
* <p> If testUser successfully authenticates itself,
* a <code>SamplePrincipal</code> with the testUser's user name
* is added to the Subject.
*
* <p> This LoginModule recognizes the debug option.
* If set to true in the login Configuration,
* debug messages will be output to the output stream, System.out.
*
*/
public class SampleLoginModule implements LoginModule {
// initial state
private Subject subject;
private CallbackHandler callbackHandler;
private Map sharedState;
private Map options;
// configurable option
private boolean debug = false;
// the authentication status
private boolean succeeded = false;
private boolean commitSucceeded = false;
// username and password
private String username;
private char[] password;
// testUser's SamplePrincipal
private SamplePrincipal userPrincipal;
/**
* Initialize this <code>LoginModule</code>.
*
* <p>
*
* @param subject the <code>Subject</code> to be authenticated. <p>
*
* @param callbackHandler a <code>CallbackHandler</code> for communicating
* with the end user (prompting for user names and
* passwords, for example). <p>
*
* @param sharedState shared <code>LoginModule</code> state. <p>
*
* @param options options specified in the login
* <code>Configuration</code> for this particular
* <code>LoginModule</code>.
*/
public void initialize(Subject subject,
CallbackHandler callbackHandler,
Map<java.lang.String, ?> sharedState,
Map<java.lang.String, ?> options) {
this.subject = subject;
this.callbackHandler = callbackHandler;
this.sharedState = sharedState;
this.options = options;
// initialize any configured options
debug = "true".equalsIgnoreCase((String)options.get("debug"));
}
/**
* Authenticate the user by prompting for a user name and password.
*
* <p>
*
* @return true in all cases since this <code>LoginModule</code>
* should not be ignored.
*
* @exception FailedLoginException if the authentication fails. <p>
*
* @exception LoginException if this <code>LoginModule</code>
* is unable to perform the authentication.
*/
public boolean login() throws LoginException {
// prompt for a user name and password
if (callbackHandler == null)
throw new LoginException("Error: no CallbackHandler available " +
"to garner authentication information from the user");
Callback[] callbacks = new Callback[2];
callbacks[0] = new NameCallback("user name: ");
callbacks[1] = new PasswordCallback("password: ", false);
try {
callbackHandler.handle(callbacks);
username = ((NameCallback)callbacks[0]).getName();
char[] tmpPassword = ((PasswordCallback)callbacks[1]).getPassword();
if (tmpPassword == null) {
// treat a NULL password as an empty password
tmpPassword = new char[0];
}
password = new char[tmpPassword.length];
System.arraycopy(tmpPassword, 0,
password, 0, tmpPassword.length);
((PasswordCallback)callbacks[1]).clearPassword();
} catch (java.io.IOException ioe) {
throw new LoginException(ioe.toString());
} catch (UnsupportedCallbackException uce) {
throw new LoginException("Error: " + uce.getCallback().toString() +
" not available to garner authentication information " +
"from the user");
}
// print debugging information
if (debug) {
System.out.println("\t\t[SampleLoginModule] " +
"user entered user name: " +
username);
System.out.print("\t\t[SampleLoginModule] " +
"user entered password: ");
for (int i = 0; i < password.length; i++)
System.out.print(password[i]);
System.out.println();
}
// verify the username/password
boolean usernameCorrect = false;
boolean passwordCorrect = false;
if (username.equals("testUser"))
usernameCorrect = true;
if (usernameCorrect &&
password.length == 12 &&
password[0] == 't' &&
password[1] == 'e' &&
password[2] == 's' &&
password[3] == 't' &&
password[4] == 'P' &&
password[5] == 'a' &&
password[6] == 's' &&
password[7] == 's' &&
password[8] == 'w' &&
password[9] == 'o' &&
password[10] == 'r' &&
password[11] == 'd') {
// authentication succeeded!!!
passwordCorrect = true;
if (debug)
System.out.println("\t\t[SampleLoginModule] " +
"authentication succeeded");
succeeded = true;
return true;
} else {
// authentication failed -- clean out state
if (debug)
System.out.println("\t\t[SampleLoginModule] " +
"authentication failed");
succeeded = false;
username = null;
for (int i = 0; i < password.length; i++)
password[i] = ' ';
password = null;
if (!usernameCorrect) {
throw new FailedLoginException("User Name Incorrect");
} else {
throw new FailedLoginException("Password Incorrect");
}
}
}
/**
* <p> This method is called if the LoginContext's
* overall authentication succeeded
* (the relevant REQUIRED, REQUISITE, SUFFICIENT and OPTIONAL LoginModules
* succeeded).
*
* <p> If this LoginModule's own authentication attempt
* succeeded (checked by retrieving the private state saved by the
* <code>login</code> method), then this method associates a
* <code>SamplePrincipal</code>
* with the <code>Subject</code> located in the
* <code>LoginModule</code>. If this LoginModule's own
* authentication attempted failed, then this method removes
* any state that was originally saved.
*
* <p>
*
* @exception LoginException if the commit fails.
*
* @return true if this LoginModule's own login and commit
* attempts succeeded, or false otherwise.
*/
public boolean commit() throws LoginException {
if (succeeded == false) {
return false;
} else {
// add a Principal (authenticated identity)
// to the Subject
// assume the user we authenticated is the SamplePrincipal
userPrincipal = new SamplePrincipal(username);
if (!subject.getPrincipals().contains(userPrincipal))
subject.getPrincipals().add(userPrincipal);
if (debug) {
System.out.println("\t\t[SampleLoginModule] " +
"added SamplePrincipal to Subject");
}
// in any case, clean out state
username = null;
for (int i = 0; i < password.length; i++)
password[i] = ' ';
password = null;
commitSucceeded = true;
return true;
}
}
/**
* <p> This method is called if the LoginContext's
* overall authentication failed.
* (the relevant REQUIRED, REQUISITE, SUFFICIENT and OPTIONAL LoginModules
* did not succeed).
*
* <p> If this LoginModule's own authentication attempt
* succeeded (checked by retrieving the private state saved by the
* <code>login</code> and <code>commit</code> methods),
* then this method cleans up any state that was originally saved.
*
* <p>
*
* @exception LoginException if the abort fails.
*
* @return false if this LoginModule's own login and/or commit attempts
* failed, and true otherwise.
*/
public boolean abort() throws LoginException {
if (succeeded == false) {
return false;
} else if (succeeded == true && commitSucceeded == false) {
// login succeeded but overall authentication failed
succeeded = false;
username = null;
if (password != null) {
for (int i = 0; i < password.length; i++)
password[i] = ' ';
password = null;
}
userPrincipal = null;
} else {
// overall authentication succeeded and commit succeeded,
// but someone else's commit failed
logout();
}
return true;
}
/**
* Logout the user.
*
* <p> This method removes the <code>SamplePrincipal</code>
* that was added by the <code>commit</code> method.
*
* <p>
*
* @exception LoginException if the logout fails.
*
* @return true in all cases since this <code>LoginModule</code>
* should not be ignored.
*/
public boolean logout() throws LoginException {
subject.getPrincipals().remove(userPrincipal);
succeeded = false;
succeeded = commitSucceeded;
username = null;
if (password != null) {
for (int i = 0; i < password.length; i++)
password[i] = ' ';
password = null;
}
userPrincipal = null;
return true;
}
}
@@ -0,0 +1,144 @@
/*
*
* Copyright (c) 2000, 2002, Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* -Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* -Redistribution in binary form must reproduct the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* Neither the name of Oracle nor the names of
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* This software is provided "AS IS," without a warranty of any
* kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
* WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
* EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY
* DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT OF OR
* RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR
* ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE
* FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT,
* SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
* CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF
* THE USE OF OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
*
* You acknowledge that Software is not designed, licensed or
* intended for use in the design, construction, operation or
* maintenance of any nuclear facility.
*/
package sample.principal;
import java.security.Principal;
/**
* <p> This class implements the <code>Principal</code> interface
* and represents a Sample user.
*
* <p> Principals such as this <code>SamplePrincipal</code>
* may be associated with a particular <code>Subject</code>
* to augment that <code>Subject</code> with an additional
* identity. Refer to the <code>Subject</code> class for more information
* on how to achieve this. Authorization decisions can then be based upon
* the Principals associated with a <code>Subject</code>.
*
* @see java.security.Principal
* @see javax.security.auth.Subject
*/
public class SamplePrincipal implements Principal, java.io.Serializable {
/**
* @serial
*/
private String name;
/**
* Create a SamplePrincipal with a Sample username.
*
* <p>
*
* @param name the Sample username for this user.
*
* @exception NullPointerException if the <code>name</code>
* is <code>null</code>.
*/
public SamplePrincipal(String name) {
if (name == null)
throw new NullPointerException("illegal null input");
this.name = name;
}
/**
* Return the Sample username for this <code>SamplePrincipal</code>.
*
* <p>
*
* @return the Sample username for this <code>SamplePrincipal</code>
*/
public String getName() {
return name;
}
/**
* Return a string representation of this <code>SamplePrincipal</code>.
*
* <p>
*
* @return a string representation of this <code>SamplePrincipal</code>.
*/
public String toString() {
return("SamplePrincipal: " + name);
}
/**
* Compares the specified Object with this <code>SamplePrincipal</code>
* for equality. Returns true if the given object is also a
* <code>SamplePrincipal</code> and the two SamplePrincipals
* have the same username.
*
* <p>
*
* @param o Object to be compared for equality with this
* <code>SamplePrincipal</code>.
*
* @return true if the specified Object is equal equal to this
* <code>SamplePrincipal</code>.
*/
public boolean equals(Object o) {
if (o == null)
return false;
if (this == o)
return true;
if (!(o instanceof SamplePrincipal))
return false;
SamplePrincipal that = (SamplePrincipal)o;
if (this.getName().equals(that.getName()))
return true;
return false;
}
/**
* Return a hash code for this <code>SamplePrincipal</code>.
*
* <p>
*
* @return a hash code for this <code>SamplePrincipal</code>.
*/
public int hashCode() {
return name.hashCode();
}
}
@@ -0,0 +1,7 @@
grant codebase "file:./SampleLM.jar" {
permission javax.security.auth.AuthPermission "modifyPrincipals";
};
grant codebase "file:./SampleAcn.jar" {
permission javax.security.auth.AuthPermission "createLoginContext.Sample";
};
@@ -0,0 +1,5 @@
/** Login Configuration for the JAAS Sample Application **/
Sample {
sample.module.SampleLoginModule required debug=true;
};
@@ -0,0 +1,28 @@
# Reset
rm \
./SampleAcn.jar \
./SampleLM.jar
# Compile Java files
javac \
sample/SampleAcn.java \
sample/module/SampleLoginModule.java \
sample/principal/SamplePrincipal.java
# Crée deux fichier Jar (SampleAcn et SampleLM)
jar -cvf SampleAcn.jar sample/SampleAcn.class sample/MyCallbackHandler.class
jar -cvf SampleLM.jar sample/module/SampleLoginModule.class sample/principal/SamplePrincipal.class
# Supprime les artéfacts
rm \
./sample/MyCallbackHandler.class \
./sample/SampleAcn.class \
./sample/module/SampleLoginModule.class \
./sample/principal/SamplePrincipal.class \
# Exécute
java -classpath SampleAcn.jar:SampleLM.jar \
-Djava.security.manager \
-Djava.security.policy==.policy \
-Djava.security.auth.login.config==jaas.config \
sample.SampleAcn
@@ -0,0 +1,237 @@
/*
*
* Copyright (c) 2001, 2002, Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* -Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* -Redistribution in binary form must reproduct the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* Neither the name of Oracle nor the names of
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* This software is provided "AS IS," without a warranty of any
* kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
* WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
* EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY
* DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT OF OR
* RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR
* ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE
* FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT,
* SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
* CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF
* THE USE OF OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
*
* You acknowledge that Software is not designed, licensed or
* intended for use in the design, construction, operation or
* maintenance of any nuclear facility.
*/
package sample;
import java.io.*;
import java.util.*;
import javax.security.auth.login.*;
import javax.security.auth.*;
import javax.security.auth.callback.*;
/**
* <p> This Sample application attempts to authenticate a user
* and reports whether or not the authentication was successful.
*/
public class SampleAcn {
/**
* Attempt to authenticate the user.
*
* <p>
*
* @param args input arguments for this application. These are ignored.
*/
public static void main(String[] args) {
// Obtain a LoginContext, needed for authentication. Tell it
// to use the LoginModule implementation specified by the
// entry named "Sample" in the JAAS login configuration
// file and to also use the specified CallbackHandler.
LoginContext lc = null;
try {
lc = new LoginContext("Sample", new MyCallbackHandler());
} catch (LoginException le) {
System.err.println("Cannot create LoginContext. " + le.getMessage());
System.exit(-1);
} catch (SecurityException se) {
System.err.println("Cannot create LoginContext. " + se.getMessage());
System.exit(-1);
}
// the user has 3 attempts to authenticate successfully
int i;
for (i = 0; i < 3; i++) {
try {
// attempt authentication
lc.login();
// if we return with no exception, authentication succeeded
break;
} catch (LoginException le) {
System.err.println("Authentication failed:");
System.err.println(" " + le.getMessage());
try {
Thread.currentThread().sleep(3000);
} catch (Exception e) {
// ignore
}
}
}
// did they fail three times?
if (i == 3) {
System.out.println("Sorry");
System.exit(-1);
}
System.out.println("Authentication succeeded!");
}
}
/**
* The application implements the CallbackHandler.
*
* <p> This application is text-based. Therefore it displays information
* to the user using the OutputStreams System.out and System.err,
* and gathers input from the user using the InputStream System.in.
*/
class MyCallbackHandler implements CallbackHandler {
/**
* Invoke an array of Callbacks.
*
* <p>
*
* @param callbacks an array of <code>Callback</code> objects which contain
* the information requested by an underlying security
* service to be retrieved or displayed.
*
* @exception java.io.IOException if an input or output error occurs. <p>
*
* @exception UnsupportedCallbackException if the implementation of this
* method does not support one or more of the Callbacks
* specified in the <code>callbacks</code> parameter.
*/
public void handle(Callback[] callbacks)
throws IOException, UnsupportedCallbackException {
for (int i = 0; i < callbacks.length; i++) {
if (callbacks[i] instanceof TextOutputCallback) {
// display the message according to the specified type
TextOutputCallback toc = (TextOutputCallback)callbacks[i];
switch (toc.getMessageType()) {
case TextOutputCallback.INFORMATION:
System.out.println(toc.getMessage());
break;
case TextOutputCallback.ERROR:
System.out.println("ERROR: " + toc.getMessage());
break;
case TextOutputCallback.WARNING:
System.out.println("WARNING: " + toc.getMessage());
break;
default:
throw new IOException("Unsupported message type: " + toc.getMessageType());
}
} else if (callbacks[i] instanceof NameCallback) {
// prompt the user for a username
NameCallback nc = (NameCallback)callbacks[i];
System.err.print(nc.getPrompt());
System.err.flush();
nc.setName((new BufferedReader
(new InputStreamReader(System.in))).readLine());
} else if (callbacks[i] instanceof PasswordCallback) {
// prompt the user for sensitive information
PasswordCallback pc = (PasswordCallback)callbacks[i];
System.err.print(pc.getPrompt());
System.err.flush();
pc.setPassword(readPassword(System.in));
} else {
throw new UnsupportedCallbackException
(callbacks[i], "Unrecognized Callback");
}
}
}
// Reads user password from given input stream.
private char[] readPassword(InputStream in) throws IOException {
char[] lineBuffer;
char[] buf;
int i;
buf = lineBuffer = new char[128];
int room = buf.length;
int offset = 0;
int c;
loop: while (true) {
switch (c = in.read()) {
case -1:
case '\n':
break loop;
case '\r':
int c2 = in.read();
if ((c2 != '\n') && (c2 != -1)) {
if (!(in instanceof PushbackInputStream)) {
in = new PushbackInputStream(in);
}
((PushbackInputStream)in).unread(c2);
} else
break loop;
default:
if (--room < 0) {
buf = new char[offset + 128];
room = buf.length - offset - 1;
System.arraycopy(lineBuffer, 0, buf, 0, offset);
Arrays.fill(lineBuffer, ' ');
lineBuffer = buf;
}
buf[offset++] = (char) c;
break;
}
}
if (offset == 0) {
return null;
}
char[] ret = new char[offset];
System.arraycopy(buf, 0, ret, 0, offset);
Arrays.fill(buf, ' ');
return ret;
}
}
@@ -0,0 +1,337 @@
/*
*
* Copyright (c) 2000, 2002, Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* -Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* -Redistribution in binary form must reproduct the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* Neither the name of Oracle nor the names of
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* This software is provided "AS IS," without a warranty of any
* kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
* WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
* EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY
* DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT OF OR
* RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR
* ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE
* FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT,
* SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
* CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF
* THE USE OF OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
*
* You acknowledge that Software is not designed, licensed or
* intended for use in the design, construction, operation or
* maintenance of any nuclear facility.
*/
package sample.module;
import java.util.*;
import java.io.IOException;
import javax.security.auth.*;
import javax.security.auth.callback.*;
import javax.security.auth.login.*;
import javax.security.auth.spi.*;
import sample.principal.SamplePrincipal;
/**
* <p> This sample LoginModule authenticates users with a password.
*
* <p> This LoginModule only recognizes one user: testUser
* <p> testUser's password is: testPassword
*
* <p> If testUser successfully authenticates itself,
* a <code>SamplePrincipal</code> with the testUser's user name
* is added to the Subject.
*
* <p> This LoginModule recognizes the debug option.
* If set to true in the login Configuration,
* debug messages will be output to the output stream, System.out.
*
*/
public class SampleLoginModule implements LoginModule {
// initial state
private Subject subject;
private CallbackHandler callbackHandler;
private Map sharedState;
private Map options;
// configurable option
private boolean debug = false;
// the authentication status
private boolean succeeded = false;
private boolean commitSucceeded = false;
// username and password
private String username;
private char[] password;
// testUser's SamplePrincipal
private SamplePrincipal userPrincipal;
/**
* Initialize this <code>LoginModule</code>.
*
* <p>
*
* @param subject the <code>Subject</code> to be authenticated. <p>
*
* @param callbackHandler a <code>CallbackHandler</code> for communicating
* with the end user (prompting for user names and
* passwords, for example). <p>
*
* @param sharedState shared <code>LoginModule</code> state. <p>
*
* @param options options specified in the login
* <code>Configuration</code> for this particular
* <code>LoginModule</code>.
*/
public void initialize(Subject subject,
CallbackHandler callbackHandler,
Map<java.lang.String, ?> sharedState,
Map<java.lang.String, ?> options) {
this.subject = subject;
this.callbackHandler = callbackHandler;
this.sharedState = sharedState;
this.options = options;
// initialize any configured options
debug = "true".equalsIgnoreCase((String)options.get("debug"));
}
/**
* Authenticate the user by prompting for a user name and password.
*
* <p>
*
* @return true in all cases since this <code>LoginModule</code>
* should not be ignored.
*
* @exception FailedLoginException if the authentication fails. <p>
*
* @exception LoginException if this <code>LoginModule</code>
* is unable to perform the authentication.
*/
public boolean login() throws LoginException {
// prompt for a user name and password
if (callbackHandler == null)
throw new LoginException("Error: no CallbackHandler available " +
"to garner authentication information from the user");
Callback[] callbacks = new Callback[2];
callbacks[0] = new NameCallback("user name: ");
callbacks[1] = new PasswordCallback("password: ", false);
try {
callbackHandler.handle(callbacks);
username = ((NameCallback)callbacks[0]).getName();
char[] tmpPassword = ((PasswordCallback)callbacks[1]).getPassword();
if (tmpPassword == null) {
// treat a NULL password as an empty password
tmpPassword = new char[0];
}
password = new char[tmpPassword.length];
System.arraycopy(tmpPassword, 0,
password, 0, tmpPassword.length);
((PasswordCallback)callbacks[1]).clearPassword();
} catch (java.io.IOException ioe) {
throw new LoginException(ioe.toString());
} catch (UnsupportedCallbackException uce) {
throw new LoginException("Error: " + uce.getCallback().toString() +
" not available to garner authentication information " +
"from the user");
}
// print debugging information
if (debug) {
System.out.println("\t\t[SampleLoginModule] " +
"user entered user name: " +
username);
System.out.print("\t\t[SampleLoginModule] " +
"user entered password: ");
for (int i = 0; i < password.length; i++)
System.out.print(password[i]);
System.out.println();
}
// verify the username/password
boolean usernameCorrect = false;
boolean passwordCorrect = false;
if (username.equals("testUser"))
usernameCorrect = true;
if (usernameCorrect &&
password.length == 12 &&
password[0] == 't' &&
password[1] == 'e' &&
password[2] == 's' &&
password[3] == 't' &&
password[4] == 'P' &&
password[5] == 'a' &&
password[6] == 's' &&
password[7] == 's' &&
password[8] == 'w' &&
password[9] == 'o' &&
password[10] == 'r' &&
password[11] == 'd') {
// authentication succeeded!!!
passwordCorrect = true;
if (debug)
System.out.println("\t\t[SampleLoginModule] " +
"authentication succeeded");
succeeded = true;
return true;
} else {
// authentication failed -- clean out state
if (debug)
System.out.println("\t\t[SampleLoginModule] " +
"authentication failed");
succeeded = false;
username = null;
for (int i = 0; i < password.length; i++)
password[i] = ' ';
password = null;
if (!usernameCorrect) {
throw new FailedLoginException("User Name Incorrect");
} else {
throw new FailedLoginException("Password Incorrect");
}
}
}
/**
* <p> This method is called if the LoginContext's
* overall authentication succeeded
* (the relevant REQUIRED, REQUISITE, SUFFICIENT and OPTIONAL LoginModules
* succeeded).
*
* <p> If this LoginModule's own authentication attempt
* succeeded (checked by retrieving the private state saved by the
* <code>login</code> method), then this method associates a
* <code>SamplePrincipal</code>
* with the <code>Subject</code> located in the
* <code>LoginModule</code>. If this LoginModule's own
* authentication attempted failed, then this method removes
* any state that was originally saved.
*
* <p>
*
* @exception LoginException if the commit fails.
*
* @return true if this LoginModule's own login and commit
* attempts succeeded, or false otherwise.
*/
public boolean commit() throws LoginException {
if (succeeded == false) {
return false;
} else {
// add a Principal (authenticated identity)
// to the Subject
// assume the user we authenticated is the SamplePrincipal
userPrincipal = new SamplePrincipal(username);
if (!subject.getPrincipals().contains(userPrincipal))
subject.getPrincipals().add(userPrincipal);
if (debug) {
System.out.println("\t\t[SampleLoginModule] " +
"added SamplePrincipal to Subject");
}
// in any case, clean out state
username = null;
for (int i = 0; i < password.length; i++)
password[i] = ' ';
password = null;
commitSucceeded = true;
return true;
}
}
/**
* <p> This method is called if the LoginContext's
* overall authentication failed.
* (the relevant REQUIRED, REQUISITE, SUFFICIENT and OPTIONAL LoginModules
* did not succeed).
*
* <p> If this LoginModule's own authentication attempt
* succeeded (checked by retrieving the private state saved by the
* <code>login</code> and <code>commit</code> methods),
* then this method cleans up any state that was originally saved.
*
* <p>
*
* @exception LoginException if the abort fails.
*
* @return false if this LoginModule's own login and/or commit attempts
* failed, and true otherwise.
*/
public boolean abort() throws LoginException {
if (succeeded == false) {
return false;
} else if (succeeded == true && commitSucceeded == false) {
// login succeeded but overall authentication failed
succeeded = false;
username = null;
if (password != null) {
for (int i = 0; i < password.length; i++)
password[i] = ' ';
password = null;
}
userPrincipal = null;
} else {
// overall authentication succeeded and commit succeeded,
// but someone else's commit failed
logout();
}
return true;
}
/**
* Logout the user.
*
* <p> This method removes the <code>SamplePrincipal</code>
* that was added by the <code>commit</code> method.
*
* <p>
*
* @exception LoginException if the logout fails.
*
* @return true in all cases since this <code>LoginModule</code>
* should not be ignored.
*/
public boolean logout() throws LoginException {
subject.getPrincipals().remove(userPrincipal);
succeeded = false;
succeeded = commitSucceeded;
username = null;
if (password != null) {
for (int i = 0; i < password.length; i++)
password[i] = ' ';
password = null;
}
userPrincipal = null;
return true;
}
}
@@ -0,0 +1,141 @@
/*
*
* Copyright (c) 2000, 2002, Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* -Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* -Redistribution in binary form must reproduct the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* Neither the name of Oracle nor the names of
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* This software is provided "AS IS," without a warranty of any
* kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
* WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
* EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY
* DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT OF OR
* RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR
* ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE
* FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT,
* SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
* CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF
* THE USE OF OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
*
* You acknowledge that Software is not designed, licensed or
* intended for use in the design, construction, operation or
* maintenance of any nuclear facility.
*/
package sample.principal;
import java.security.Principal;
/**
* <p> This class implements the <code>Principal</code> interface
* and represents a Sample user.
*
* <p> Principals such as this <code>SamplePrincipal</code>
* may be associated with a particular <code>Subject</code>
* to augment that <code>Subject</code> with an additional
* identity. Refer to the <code>Subject</code> class for more information
* on how to achieve this. Authorization decisions can then be based upon
* the Principals associated with a <code>Subject</code>.
*
* @see java.security.Principal
* @see javax.security.auth.Subject
*/
public class SamplePrincipal implements Principal, java.io.Serializable {
/**
* @serial
*/
private String name;
/**
* Create a SamplePrincipal with a Sample username.
*
* <p>
*
* @param name the Sample username for this user.
*
* @exception NullPointerException if the <code>name</code>
* is <code>null</code>.
*/
public SamplePrincipal(String name) {
if (name == null)
throw new NullPointerException("illegal null input");
this.name = name;
}
/**
* Return the Sample username for this <code>SamplePrincipal</code>.
*
* <p>
*
* @return the Sample username for this <code>SamplePrincipal</code>
*/
public String getName() {
return name;
}
/**
* Return a string representation of this <code>SamplePrincipal</code>.
*
* <p>
*
* @return a string representation of this <code>SamplePrincipal</code>.
*/
public String toString() {
return("SamplePrincipal: " + name);
}
/**
* Compares the specified Object with this <code>SamplePrincipal</code>
* for equality. Returns true if the given object is also a
* <code>SamplePrincipal</code> and the two SamplePrincipals
* have the same username.
*
* <p>
*
* @param o Object to be compared for equality with this
* <code>SamplePrincipal</code>.
*
* @return true if the specified Object is equal equal to this
* <code>SamplePrincipal</code>.
*/
public boolean equals(Object o) {
if (o == null) return false;
if (this == o) return true;
if (!(o instanceof SamplePrincipal))
return false;
SamplePrincipal that = (SamplePrincipal)o;
if (this.getName().equals(that.getName()))
return true;
return false;
}
/**
* Return a hash code for this <code>SamplePrincipal</code>.
*
* <p>
*
* @return a hash code for this <code>SamplePrincipal</code>.
*/
public int hashCode() {
return name.hashCode();
}
}
@@ -0,0 +1,24 @@
/** Java 2 Access Control Policy for the JAAS Sample Application **/
/* grant the sample LoginModule permissions */
grant codebase "file:./SampleLM.jar" {
permission javax.security.auth.AuthPermission "modifyPrincipals";
};
grant codebase "file:./SampleAzn.jar" {
permission javax.security.auth.AuthPermission "createLoginContext.Sample";
permission javax.security.auth.AuthPermission "doAsPrivileged";
};
/** User-Based Access Control Policy for the SampleAction class
** instantiated by SampleAzn
**/
grant codebase "file:./SampleAction.jar",
Principal sample.principal.SamplePrincipal "testUser" {
permission java.util.PropertyPermission "java.home", "read";
permission java.util.PropertyPermission "user.home", "read";
permission java.io.FilePermission "foo.txt", "read";
};
@@ -0,0 +1 @@
Coucou c'est moi FOO
@@ -0,0 +1,5 @@
/** Login Configuration for the JAAS Sample Application **/
Sample {
sample.module.SampleLoginModule required debug=true;
};
@@ -0,0 +1,31 @@
# Reset
rm \
./SampleAcn.jar \
./SampleAction.jar \
./SampleLM.jar
# Compile
javac \
sample/SampleAction.java \
sample/SampleAzn.java \
sample/module/SampleLoginModule.java \
sample/principal/SamplePrincipal.java
# Créé les JAR SampleAzn, SampleAction, SampleLM
jar -cvf SampleAzn.jar sample/SampleAzn.class sample/MyCallbackHandler.class
jar -cvf SampleAction.jar sample/SampleAction.class
jar -cvf SampleLM.jar sample/module/SampleLoginModule.class sample/principal/SamplePrincipal.class
# Enlève les artéfacts
rm \
./sample/SampleAction.class \
./sample/SampleAzn.class \
./sample/MyCallbackHandler.class \
./sample/module/SampleLoginModule.class \
./sample/principal/SamplePrincipal.class
# Executer
java -classpath SampleAzn.jar:SampleAction.jar:SampleLM.jar \
-Djava.security.manager \
-Djava.security.policy==azn.policy \
-Djava.security.auth.login.config==jaas.config sample.SampleAzn
@@ -0,0 +1,75 @@
/*
*
* Copyright (c) 2000, 2002, Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* -Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* -Redistribution in binary form must reproduct the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* Neither the name of Oracle nor the names of
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* This software is provided "AS IS," without a warranty of any
* kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
* WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
* EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY
* DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT OF OR
* RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR
* ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE
* FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT,
* SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
* CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF
* THE USE OF OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
*
* You acknowledge that Software is not designed, licensed or
* intended for use in the design, construction, operation or
* maintenance of any nuclear facility.
*/
package sample;
import java.io.File;
import java.security.PrivilegedAction;
/**
* <p> This is a Sample PrivilegedAction implementation, designed to be
* used with the Sample application.
*
*/
public class SampleAction implements PrivilegedAction {
/**
* <p> This Sample PrivilegedAction performs the following operations:
* <ul>
* <li> Access the System property, <i>java.home</i>
* <li> Access the System property, <i>user.home</i>
* <li> Access the file, <i>foo.txt</i>
* </ul>
*
* @return <code>null</code> in all cases.
*
* @exception SecurityException if the caller does not have permission
* to perform the operations listed above.
*/
public Object run() {
System.out.println("java.home : " + System.getProperty("java.home"));
System.out.println("user.home : " + System.getProperty("user.home"));
File f = new File("foo.txt");
System.out.print("foo.txt does ");
if (!f.exists()) System.out.print("not ");
System.out.println("exist in the current working directory.");
return null;
}
}
@@ -0,0 +1,265 @@
/*
*
* Copyright (c) 2001, 2002, Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* -Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* -Redistribution in binary form must reproduct the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* Neither the name of Oracle nor the names of
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* This software is provided "AS IS," without a warranty of any
* kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
* WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
* EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY
* DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT OF OR
* RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR
* ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE
* FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT,
* SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
* CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF
* THE USE OF OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
*
* You acknowledge that Software is not designed, licensed or
* intended for use in the design, construction, operation or
* maintenance of any nuclear facility.
*/
package sample;
import java.io.*;
import java.util.*;
import java.security.Principal;
import java.security.PrivilegedAction;
import javax.security.auth.*;
import javax.security.auth.callback.*;
import javax.security.auth.login.*;
import javax.security.auth.spi.*;
import com.sun.security.auth.*;
/**
* <p> This Sample application attempts to authenticate a user
* and executes a SampleAction as that user.
*
* <p> If the user successfully authenticates itself,
* the username and number of Credentials is displayed.
*/
public class SampleAzn {
/**
* Attempt to authenticate the user.
*
* <p>
*
* @param args input arguments for this application. These are ignored.
*/
public static void main(String[] args) {
// Obtain a LoginContext, needed for authentication. Tell it
// to use the LoginModule implementation specified by the
// entry named "Sample" in the JAAS login configuration
// file and to also use the specified CallbackHandler.
LoginContext lc = null;
try {
lc = new LoginContext("Sample", new MyCallbackHandler());
} catch (LoginException le) {
System.err.println("Cannot create LoginContext. "
+ le.getMessage());
System.exit(-1);
} catch (SecurityException se) {
System.err.println("Cannot create LoginContext. "
+ se.getMessage());
System.exit(-1);
}
// the user has 3 attempts to authenticate successfully
int i;
for (i = 0; i < 3; i++) {
try {
// attempt authentication
lc.login();
// if we return with no exception, authentication succeeded
break;
} catch (LoginException le) {
System.err.println("Authentication failed:");
System.err.println(" " + le.getMessage());
try {
Thread.currentThread().sleep(3000);
} catch (Exception e) {
// ignore
}
}
}
// did they fail three times?
if (i == 3) {
System.out.println("Sorry");
System.exit(-1);
}
System.out.println("Authentication succeeded!");
Subject mySubject = lc.getSubject();
// let's see what Principals we have
Iterator principalIterator = mySubject.getPrincipals().iterator();
System.out.println("Authenticated user has the following Principals:");
while (principalIterator.hasNext()) {
Principal p = (Principal)principalIterator.next();
System.out.println("\t" + p.toString());
}
System.out.println("User has " +
mySubject.getPublicCredentials().size() +
" Public Credential(s)");
// now try to execute the SampleAction as the authenticated Subject
PrivilegedAction action = new SampleAction();
Subject.doAsPrivileged(mySubject, action, null);
System.exit(0);
}
}
/**
* A CallbackHandler implemented by the application.
*
* <p> This application is text-based. Therefore it displays information
* to the user using the OutputStreams System.out and System.err,
* and gathers input from the user using the InputStream System.in.
*/
class MyCallbackHandler implements CallbackHandler {
/**
* Invoke an array of Callbacks.
*
* <p>
*
* @param callbacks an array of <code>Callback</code> objects which contain
* the information requested by an underlying security
* service to be retrieved or displayed.
*
* @exception java.io.IOException if an input or output error occurs. <p>
*
* @exception UnsupportedCallbackException if the implementation of this
* method does not support one or more of the Callbacks
* specified in the <code>callbacks</code> parameter.
*/
public void handle(Callback[] callbacks)
throws IOException, UnsupportedCallbackException {
for (int i = 0; i < callbacks.length; i++) {
if (callbacks[i] instanceof TextOutputCallback) {
// display the message according to the specified type
TextOutputCallback toc = (TextOutputCallback)callbacks[i];
switch (toc.getMessageType()) {
case TextOutputCallback.INFORMATION:
System.out.println(toc.getMessage());
break;
case TextOutputCallback.ERROR:
System.out.println("ERROR: " + toc.getMessage());
break;
case TextOutputCallback.WARNING:
System.out.println("WARNING: " + toc.getMessage());
break;
default:
throw new IOException("Unsupported message type: " +
toc.getMessageType());
}
} else if (callbacks[i] instanceof NameCallback) {
// prompt the user for a username
NameCallback nc = (NameCallback)callbacks[i];
System.err.print(nc.getPrompt());
System.err.flush();
nc.setName((new BufferedReader
(new InputStreamReader(System.in))).readLine());
} else if (callbacks[i] instanceof PasswordCallback) {
// prompt the user for sensitive information
PasswordCallback pc = (PasswordCallback)callbacks[i];
System.err.print(pc.getPrompt());
System.err.flush();
pc.setPassword(readPassword(System.in));
} else {
throw new UnsupportedCallbackException
(callbacks[i], "Unrecognized Callback");
}
}
}
// Reads user password from given input stream.
private char[] readPassword(InputStream in) throws IOException {
char[] lineBuffer;
char[] buf;
int i;
buf = lineBuffer = new char[128];
int room = buf.length;
int offset = 0;
int c;
loop: while (true) {
switch (c = in.read()) {
case -1:
case '\n':
break loop;
case '\r':
int c2 = in.read();
if ((c2 != '\n') && (c2 != -1)) {
if (!(in instanceof PushbackInputStream)) {
in = new PushbackInputStream(in);
}
((PushbackInputStream)in).unread(c2);
} else
break loop;
default:
if (--room < 0) {
buf = new char[offset + 128];
room = buf.length - offset - 1;
System.arraycopy(lineBuffer, 0, buf, 0, offset);
Arrays.fill(lineBuffer, ' ');
lineBuffer = buf;
}
buf[offset++] = (char) c;
break;
}
}
if (offset == 0) {
return null;
}
char[] ret = new char[offset];
System.arraycopy(buf, 0, ret, 0, offset);
Arrays.fill(buf, ' ');
return ret;
}
}
@@ -0,0 +1,337 @@
/*
*
* Copyright (c) 2000, 2002, Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* -Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* -Redistribution in binary form must reproduct the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* Neither the name of Oracle nor the names of
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* This software is provided "AS IS," without a warranty of any
* kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
* WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
* EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY
* DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT OF OR
* RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR
* ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE
* FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT,
* SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
* CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF
* THE USE OF OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
*
* You acknowledge that Software is not designed, licensed or
* intended for use in the design, construction, operation or
* maintenance of any nuclear facility.
*/
package sample.module;
import java.util.*;
import java.io.IOException;
import javax.security.auth.*;
import javax.security.auth.callback.*;
import javax.security.auth.login.*;
import javax.security.auth.spi.*;
import sample.principal.SamplePrincipal;
/**
* <p> This sample LoginModule authenticates users with a password.
*
* <p> This LoginModule only recognizes one user: testUser
* <p> testUser's password is: testPassword
*
* <p> If testUser successfully authenticates itself,
* a <code>SamplePrincipal</code> with the testUser's user name
* is added to the Subject.
*
* <p> This LoginModule recognizes the debug option.
* If set to true in the login Configuration,
* debug messages will be output to the output stream, System.out.
*
*/
public class SampleLoginModule implements LoginModule {
// initial state
private Subject subject;
private CallbackHandler callbackHandler;
private Map sharedState;
private Map options;
// configurable option
private boolean debug = false;
// the authentication status
private boolean succeeded = false;
private boolean commitSucceeded = false;
// username and password
private String username;
private char[] password;
// testUser's SamplePrincipal
private SamplePrincipal userPrincipal;
/**
* Initialize this <code>LoginModule</code>.
*
* <p>
*
* @param subject the <code>Subject</code> to be authenticated. <p>
*
* @param callbackHandler a <code>CallbackHandler</code> for communicating
* with the end user (prompting for user names and
* passwords, for example). <p>
*
* @param sharedState shared <code>LoginModule</code> state. <p>
*
* @param options options specified in the login
* <code>Configuration</code> for this particular
* <code>LoginModule</code>.
*/
public void initialize(Subject subject,
CallbackHandler callbackHandler,
Map<java.lang.String, ?> sharedState,
Map<java.lang.String, ?> options) {
this.subject = subject;
this.callbackHandler = callbackHandler;
this.sharedState = sharedState;
this.options = options;
// initialize any configured options
debug = "true".equalsIgnoreCase((String)options.get("debug"));
}
/**
* Authenticate the user by prompting for a user name and password.
*
* <p>
*
* @return true in all cases since this <code>LoginModule</code>
* should not be ignored.
*
* @exception FailedLoginException if the authentication fails. <p>
*
* @exception LoginException if this <code>LoginModule</code>
* is unable to perform the authentication.
*/
public boolean login() throws LoginException {
// prompt for a user name and password
if (callbackHandler == null)
throw new LoginException("Error: no CallbackHandler available " +
"to garner authentication information from the user");
Callback[] callbacks = new Callback[2];
callbacks[0] = new NameCallback("user name: ");
callbacks[1] = new PasswordCallback("password: ", false);
try {
callbackHandler.handle(callbacks);
username = ((NameCallback)callbacks[0]).getName();
char[] tmpPassword = ((PasswordCallback)callbacks[1]).getPassword();
if (tmpPassword == null) {
// treat a NULL password as an empty password
tmpPassword = new char[0];
}
password = new char[tmpPassword.length];
System.arraycopy(tmpPassword, 0,
password, 0, tmpPassword.length);
((PasswordCallback)callbacks[1]).clearPassword();
} catch (java.io.IOException ioe) {
throw new LoginException(ioe.toString());
} catch (UnsupportedCallbackException uce) {
throw new LoginException("Error: " + uce.getCallback().toString() +
" not available to garner authentication information " +
"from the user");
}
// print debugging information
if (debug) {
System.out.println("\t\t[SampleLoginModule] " +
"user entered user name: " +
username);
System.out.print("\t\t[SampleLoginModule] " +
"user entered password: ");
for (int i = 0; i < password.length; i++)
System.out.print(password[i]);
System.out.println();
}
// verify the username/password
boolean usernameCorrect = false;
boolean passwordCorrect = false;
if (username.equals("testUser"))
usernameCorrect = true;
if (usernameCorrect &&
password.length == 12 &&
password[0] == 't' &&
password[1] == 'e' &&
password[2] == 's' &&
password[3] == 't' &&
password[4] == 'P' &&
password[5] == 'a' &&
password[6] == 's' &&
password[7] == 's' &&
password[8] == 'w' &&
password[9] == 'o' &&
password[10] == 'r' &&
password[11] == 'd') {
// authentication succeeded!!!
passwordCorrect = true;
if (debug)
System.out.println("\t\t[SampleLoginModule] " +
"authentication succeeded");
succeeded = true;
return true;
} else {
// authentication failed -- clean out state
if (debug)
System.out.println("\t\t[SampleLoginModule] " +
"authentication failed");
succeeded = false;
username = null;
for (int i = 0; i < password.length; i++)
password[i] = ' ';
password = null;
if (!usernameCorrect) {
throw new FailedLoginException("User Name Incorrect");
} else {
throw new FailedLoginException("Password Incorrect");
}
}
}
/**
* <p> This method is called if the LoginContext's
* overall authentication succeeded
* (the relevant REQUIRED, REQUISITE, SUFFICIENT and OPTIONAL LoginModules
* succeeded).
*
* <p> If this LoginModule's own authentication attempt
* succeeded (checked by retrieving the private state saved by the
* <code>login</code> method), then this method associates a
* <code>SamplePrincipal</code>
* with the <code>Subject</code> located in the
* <code>LoginModule</code>. If this LoginModule's own
* authentication attempted failed, then this method removes
* any state that was originally saved.
*
* <p>
*
* @exception LoginException if the commit fails.
*
* @return true if this LoginModule's own login and commit
* attempts succeeded, or false otherwise.
*/
public boolean commit() throws LoginException {
if (succeeded == false) {
return false;
} else {
// add a Principal (authenticated identity)
// to the Subject
// assume the user we authenticated is the SamplePrincipal
userPrincipal = new SamplePrincipal(username);
if (!subject.getPrincipals().contains(userPrincipal))
subject.getPrincipals().add(userPrincipal);
if (debug) {
System.out.println("\t\t[SampleLoginModule] " +
"added SamplePrincipal to Subject");
}
// in any case, clean out state
username = null;
for (int i = 0; i < password.length; i++)
password[i] = ' ';
password = null;
commitSucceeded = true;
return true;
}
}
/**
* <p> This method is called if the LoginContext's
* overall authentication failed.
* (the relevant REQUIRED, REQUISITE, SUFFICIENT and OPTIONAL LoginModules
* did not succeed).
*
* <p> If this LoginModule's own authentication attempt
* succeeded (checked by retrieving the private state saved by the
* <code>login</code> and <code>commit</code> methods),
* then this method cleans up any state that was originally saved.
*
* <p>
*
* @exception LoginException if the abort fails.
*
* @return false if this LoginModule's own login and/or commit attempts
* failed, and true otherwise.
*/
public boolean abort() throws LoginException {
if (succeeded == false) {
return false;
} else if (succeeded == true && commitSucceeded == false) {
// login succeeded but overall authentication failed
succeeded = false;
username = null;
if (password != null) {
for (int i = 0; i < password.length; i++)
password[i] = ' ';
password = null;
}
userPrincipal = null;
} else {
// overall authentication succeeded and commit succeeded,
// but someone else's commit failed
logout();
}
return true;
}
/**
* Logout the user.
*
* <p> This method removes the <code>SamplePrincipal</code>
* that was added by the <code>commit</code> method.
*
* <p>
*
* @exception LoginException if the logout fails.
*
* @return true in all cases since this <code>LoginModule</code>
* should not be ignored.
*/
public boolean logout() throws LoginException {
subject.getPrincipals().remove(userPrincipal);
succeeded = false;
succeeded = commitSucceeded;
username = null;
if (password != null) {
for (int i = 0; i < password.length; i++)
password[i] = ' ';
password = null;
}
userPrincipal = null;
return true;
}
}
@@ -0,0 +1,144 @@
/*
*
* Copyright (c) 2000, 2002, Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* -Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* -Redistribution in binary form must reproduct the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* Neither the name of Oracle nor the names of
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* This software is provided "AS IS," without a warranty of any
* kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
* WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
* EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY
* DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT OF OR
* RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR
* ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE
* FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT,
* SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
* CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF
* THE USE OF OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
*
* You acknowledge that Software is not designed, licensed or
* intended for use in the design, construction, operation or
* maintenance of any nuclear facility.
*/
package sample.principal;
import java.security.Principal;
/**
* <p> This class implements the <code>Principal</code> interface
* and represents a Sample user.
*
* <p> Principals such as this <code>SamplePrincipal</code>
* may be associated with a particular <code>Subject</code>
* to augment that <code>Subject</code> with an additional
* identity. Refer to the <code>Subject</code> class for more information
* on how to achieve this. Authorization decisions can then be based upon
* the Principals associated with a <code>Subject</code>.
*
* @see java.security.Principal
* @see javax.security.auth.Subject
*/
public class SamplePrincipal implements Principal, java.io.Serializable {
/**
* @serial
*/
private String name;
/**
* Create a SamplePrincipal with a Sample username.
*
* <p>
*
* @param name the Sample username for this user.
*
* @exception NullPointerException if the <code>name</code>
* is <code>null</code>.
*/
public SamplePrincipal(String name) {
if (name == null)
throw new NullPointerException("illegal null input");
this.name = name;
}
/**
* Return the Sample username for this <code>SamplePrincipal</code>.
*
* <p>
*
* @return the Sample username for this <code>SamplePrincipal</code>
*/
public String getName() {
return name;
}
/**
* Return a string representation of this <code>SamplePrincipal</code>.
*
* <p>
*
* @return a string representation of this <code>SamplePrincipal</code>.
*/
public String toString() {
return("SamplePrincipal: " + name);
}
/**
* Compares the specified Object with this <code>SamplePrincipal</code>
* for equality. Returns true if the given object is also a
* <code>SamplePrincipal</code> and the two SamplePrincipals
* have the same username.
*
* <p>
*
* @param o Object to be compared for equality with this
* <code>SamplePrincipal</code>.
*
* @return true if the specified Object is equal equal to this
* <code>SamplePrincipal</code>.
*/
public boolean equals(Object o) {
if (o == null)
return false;
if (this == o)
return true;
if (!(o instanceof SamplePrincipal))
return false;
SamplePrincipal that = (SamplePrincipal)o;
if (this.getName().equals(that.getName()))
return true;
return false;
}
/**
* Return a hash code for this <code>SamplePrincipal</code>.
*
* <p>
*
* @return a hash code for this <code>SamplePrincipal</code>.
*/
public int hashCode() {
return name.hashCode();
}
}
+112
View File
@@ -0,0 +1,112 @@
#!/bin/bash
# Reset
rm -rf ./CA
rm ./client/certificat_request.csr \
./client/certificat_signed.cer \
./client/certificat.cer \
./client/keystore.jks \
./client/Source_Signed.jar
##########################################
# Création des dossiers CA et client s'ils n'existent pas déjà
mkdir -p CA client
# Génération de la clé privée de la CA
openssl genrsa -out CA/ca.key 2048
echo "[CA] - génération de la clé privée : OK"
# Génération du certificat auto-signé de la CA
openssl req -x509 -new -nodes \
-key CA/ca.key -sha256 -days 365 \
-out CA/ca.crt \
-subj "/CN=SimulatedCA/O=MyCA/C=FR"
echo "[CA] - génération du certificat auto-signé : OK"
# Génération du keystore du client
keytool -genkeypair \
-alias KeyAlias \
-keyalg RSA \
-keysize 2048 \
-keystore client/keystore.jks \
-validity 365 \
-dname "CN=ClientName, OU=ClientUnit, O=ClientOrg, L=ClientCity, S=ClientState, C=FR" \
-storepass changeit \
-keypass changeit
echo "[Client] - Génération du keystore : OK"
# Génération de la demande de certificat (CSR) pour le client
keytool -certreq \
-alias KeyAlias \
-keystore client/keystore.jks \
-file client/certificat_request.csr \
-storepass changeit
echo "[Client] - Génération de la demande de certification : OK"
# La CA signe la demande de certificat du client
openssl x509 -req \
-in client/certificat_request.csr \
-CA CA/ca.crt -CAkey CA/ca.key -CAcreateserial \
-out client/certificat_signed.cer -days 365 -sha256
echo "[CA] - Signature de la demande de certificat : OK"
# Importation du certificat de la CA dans le keystore du client
keytool -import \
-trustcacerts \
-alias SimulatedCA \
-file CA/ca.crt \
-keystore client/keystore.jks \
-noprompt \
-storepass changeit
echo "[Client] - Import du certificat du CA : OK"
# Importation du certificat signé dans le keystore du client
keytool -import \
-alias KeyAlias \
-keystore client/keystore.jks \
-file client/certificat_signed.cer \
-noprompt \
-storepass changeit
echo "[Client] - Import du certificat signé : OK"
# Exportation du certificat signé pour distribution
keytool -export \
-alias KeyAlias \
-keystore client/keystore.jks \
-file client/certificat.cer \
-storepass changeit
echo "[Client] - Export du certificat signé : OK"
##########################################
cd ./client/
# Compile notre fichier java
javac ./Source.java
echo "[Client] - Compilation du .java : OK"
# Créer un fichier MANIFEST.MF avec l'attribut Main-Class
echo "Main-Class: Source" > ./MANIFEST.MF
# Créé le fichier Jar non signé
jar cmf ./MANIFEST.MF ./Source.jar ./Source.class
echo "[Client] - Creation du fichier .jar : OK"
# Convertis en fichier jar signé
jarsigner -keystore ./keystore.jks \
-storepass changeit \
-signedjar ./Source_Signed.jar ./Source.jar KeyAlias
echo "[Client] - Creation du fichier .jar signé : OK"
# Supprime les artéfacts
rm ./Source.class ./Source.jar ./MANIFEST.MF
# On peut vérifier que notre certificat est bien valide
jarsigner -verify ./Source_Signed.jar
echo "[Client] - Vérification du certificat : OK"
cd ..
# Executer le jar signé
java -jar ./client/Source_Signed.jar
+29
View File
@@ -0,0 +1,29 @@
# Reset
rm ./keystore.jks ./Source_Signed.jar
# Génère un keystore
keytool -genkeypair \
-alias SourceKeyAlias \
-keyalg RSA \
-keysize 2048 \
-keystore keystore.jks \
-validity 365
# Compilation
javac ./Source.java
# Créer un fichier MANIFEST.MF avec l'attribut Main-Class
echo "Main-Class: Source" > MANIFEST.MF
# Crée le fichier JAR non signé avec le MANIFEST.MF modifié
jar cmf MANIFEST.MF Source.jar Source.class
# Convertir en fichier JAR signé
jarsigner -keystore keystore.jks \
-signedjar Source_Signed.jar Source.jar SourceKeyAlias
# Supprime les artéfacts
rm ./Source.class ./Source.jar MANIFEST.MF
# Essaye d'exécuter ton fichier JAR signé
java -jar Source_Signed.jar