Skip to content

Instantly share code, notes, and snippets.

@ekoontz
Created November 18, 2010 17:26
Show Gist options
  • Save ekoontz/705310 to your computer and use it in GitHub Desktop.
Save ekoontz/705310 to your computer and use it in GitHub Desktop.
/*
* @(#)SampleServer.java
*
* 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 or 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.
*/
import org.ietf.jgss.*;
import java.io.*;
import java.net.Socket;
import java.net.ServerSocket;
/**
* A sample server application that uses JGSS to do mutual authentication
* with a client using Kerberos as the underlying mechanism. It then
* exchanges data securely with the client.
*
* Every message exchanged with the client includes a 4-byte application-
* level header that contains the big-endian integer value for the number
* of bytes that will follow as part of the JGSS token.
*
* The protocol is:
* 1. Context establishment loop:
* a. client sends init sec context token to server
* b. server sends accept sec context token to client
* ....
* 2. client sends a wrap token to the server.
* 3. server sends a mic token to the client for the application
* message that was contained in the wrap token.
*/
public class SampleServer {
public static void main(String[] args)
throws IOException, GSSException {
// Obtain the command-line arguments and parse the port number
if (args.length != 1) {
System.err.println("Usage: java <options> Login SampleServer <localPort>");
System.exit(-1);
}
int localPort = Integer.parseInt(args[0]);
ServerSocket ss = new ServerSocket(localPort);
GSSManager manager = GSSManager.getInstance();
while (true) {
System.out.println("Waiting for incoming connection...");
Socket socket = ss.accept();
DataInputStream inStream =
new DataInputStream(socket.getInputStream());
DataOutputStream outStream =
new DataOutputStream(socket.getOutputStream());
System.out.println("Got connection from client "
+ socket.getInetAddress());
/*
* Create a GSSContext to receive the incoming request
* from the client. Use null for the server credentials
* passed in. This tells the underlying mechanism
* to use whatever credentials it has available that
* can be used to accept this connection.
*/
GSSContext context = manager.createContext((GSSCredential)null);
// Do the context eastablishment loop
byte[] token = null;
while (!context.isEstablished()) {
token = new byte[inStream.readInt()];
System.out.println("Will read input token of size "
+ token.length
+ " for processing by acceptSecContext");
inStream.readFully(token);
token = context.acceptSecContext(token, 0, token.length);
// Send a token to the peer if one was generated by
// acceptSecContext
if (token != null) {
System.out.println("Will send token of size "
+ token.length
+ " from acceptSecContext.");
outStream.writeInt(token.length);
outStream.write(token);
outStream.flush();
}
}
System.out.print("Context Established! ");
System.out.println("Client is " + context.getSrcName());
System.out.println("Server is " + context.getTargName());
/*
* If mutual authentication did not take place, then
* only the client was authenticated to the
* server. Otherwise, both client and server were
* authenticated to each other.
*/
if (context.getMutualAuthState())
System.out.println("Mutual authentication took place!");
/*
* Create a MessageProp which unwrap will use to return
* information such as the Quality-of-Protection that was
* applied to the wrapped token, whether or not it was
* encrypted, etc. Since the initial MessageProp values
* are ignored, just set them to the defaults of 0 and false.
*/
MessageProp prop = new MessageProp(0, false);
/*
* Read the token. This uses the same token byte array
* as that used during context establishment.
*/
token = new byte[inStream.readInt()];
System.out.println("Will read token of size "
+ token.length);
inStream.readFully(token);
byte[] bytes = context.unwrap(token, 0, token.length, prop);
String str = new String(bytes);
System.out.println("Received data \""
+ str + "\" of length " + str.length());
System.out.println("Confidentiality applied: "
+ prop.getPrivacy());
/*
* Now generate a MIC and send it to the client. This is
* just for illustration purposes. The integrity of the
* incoming wrapped message is guaranteed irrespective of
* the confidentiality (encryption) that was used.
*/
/*
* First reset the QOP of the MessageProp to 0
* to ensure the default Quality-of-Protection
* is applied.
*/
prop.setQOP(0);
token = context.getMIC(bytes, 0, bytes.length, prop);
System.out.println("Will send MIC token of size "
+ token.length);
outStream.writeInt(token.length);
outStream.write(token);
outStream.flush();
System.out.println("Closing connection with client "
+ socket.getInetAddress());
context.dispose();
socket.close();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment