http://git-wip-us.apache.org/repos/asf/accumulo/blob/2c983317/core/src/main/java/org/apache/accumulo/core/master/thrift/MasterClientService.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/accumulo/core/master/thrift/MasterClientService.java b/core/src/main/java/org/apache/accumulo/core/master/thrift/MasterClientService.java index 4b90a34..9cd1084 100644 --- a/core/src/main/java/org/apache/accumulo/core/master/thrift/MasterClientService.java +++ b/core/src/main/java/org/apache/accumulo/core/master/thrift/MasterClientService.java @@ -84,6 +84,8 @@ import org.slf4j.LoggerFactory; public List<String> getActiveTservers(org.apache.accumulo.core.trace.thrift.TInfo tinfo, org.apache.accumulo.core.security.thrift.TCredentials credentials) throws org.apache.accumulo.core.client.impl.thrift.ThriftSecurityException, org.apache.thrift.TException; + public org.apache.accumulo.core.security.thrift.TDelegationToken getDelegationToken(org.apache.accumulo.core.trace.thrift.TInfo tinfo, org.apache.accumulo.core.security.thrift.TCredentials credentials, org.apache.accumulo.core.security.thrift.TDelegationTokenConfig cfg) throws org.apache.accumulo.core.client.impl.thrift.ThriftSecurityException, org.apache.thrift.TException; + } public interface AsyncIface extends FateService .AsyncIface { @@ -120,6 +122,8 @@ import org.slf4j.LoggerFactory; public void getActiveTservers(org.apache.accumulo.core.trace.thrift.TInfo tinfo, org.apache.accumulo.core.security.thrift.TCredentials credentials, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException; + public void getDelegationToken(org.apache.accumulo.core.trace.thrift.TInfo tinfo, org.apache.accumulo.core.security.thrift.TCredentials credentials, org.apache.accumulo.core.security.thrift.TDelegationTokenConfig cfg, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException; + } public static class Client extends FateService.Client implements Iface { @@ -555,6 +559,34 @@ import org.slf4j.LoggerFactory; throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getActiveTservers failed: unknown result"); } + public org.apache.accumulo.core.security.thrift.TDelegationToken getDelegationToken(org.apache.accumulo.core.trace.thrift.TInfo tinfo, org.apache.accumulo.core.security.thrift.TCredentials credentials, org.apache.accumulo.core.security.thrift.TDelegationTokenConfig cfg) throws org.apache.accumulo.core.client.impl.thrift.ThriftSecurityException, org.apache.thrift.TException + { + send_getDelegationToken(tinfo, credentials, cfg); + return recv_getDelegationToken(); + } + + public void send_getDelegationToken(org.apache.accumulo.core.trace.thrift.TInfo tinfo, org.apache.accumulo.core.security.thrift.TCredentials credentials, org.apache.accumulo.core.security.thrift.TDelegationTokenConfig cfg) throws org.apache.thrift.TException + { + getDelegationToken_args args = new getDelegationToken_args(); + args.setTinfo(tinfo); + args.setCredentials(credentials); + args.setCfg(cfg); + sendBase("getDelegationToken", args); + } + + public org.apache.accumulo.core.security.thrift.TDelegationToken recv_getDelegationToken() throws org.apache.accumulo.core.client.impl.thrift.ThriftSecurityException, org.apache.thrift.TException + { + getDelegationToken_result result = new getDelegationToken_result(); + receiveBase(result, "getDelegationToken"); + if (result.isSetSuccess()) { + return result.success; + } + if (result.sec != null) { + throw result.sec; + } + throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getDelegationToken failed: unknown result"); + } + } public static class AsyncClient extends FateService.AsyncClient implements AsyncIface { public static class Factory implements org.apache.thrift.async.TAsyncClientFactory<AsyncClient> { @@ -1212,6 +1244,44 @@ import org.slf4j.LoggerFactory; } } + public void getDelegationToken(org.apache.accumulo.core.trace.thrift.TInfo tinfo, org.apache.accumulo.core.security.thrift.TCredentials credentials, org.apache.accumulo.core.security.thrift.TDelegationTokenConfig cfg, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException { + checkReady(); + getDelegationToken_call method_call = new getDelegationToken_call(tinfo, credentials, cfg, resultHandler, this, ___protocolFactory, ___transport); + this.___currentMethod = method_call; + ___manager.call(method_call); + } + + public static class getDelegationToken_call extends org.apache.thrift.async.TAsyncMethodCall { + private org.apache.accumulo.core.trace.thrift.TInfo tinfo; + private org.apache.accumulo.core.security.thrift.TCredentials credentials; + private org.apache.accumulo.core.security.thrift.TDelegationTokenConfig cfg; + public getDelegationToken_call(org.apache.accumulo.core.trace.thrift.TInfo tinfo, org.apache.accumulo.core.security.thrift.TCredentials credentials, org.apache.accumulo.core.security.thrift.TDelegationTokenConfig cfg, org.apache.thrift.async.AsyncMethodCallback resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException { + super(client, protocolFactory, transport, resultHandler, false); + this.tinfo = tinfo; + this.credentials = credentials; + this.cfg = cfg; + } + + public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException { + prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("getDelegationToken", org.apache.thrift.protocol.TMessageType.CALL, 0)); + getDelegationToken_args args = new getDelegationToken_args(); + args.setTinfo(tinfo); + args.setCredentials(credentials); + args.setCfg(cfg); + args.write(prot); + prot.writeMessageEnd(); + } + + public org.apache.accumulo.core.security.thrift.TDelegationToken getResult() throws org.apache.accumulo.core.client.impl.thrift.ThriftSecurityException, org.apache.thrift.TException { + if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) { + throw new IllegalStateException("Method call not finished!"); + } + org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array()); + org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport); + return (new Client(prot)).recv_getDelegationToken(); + } + } + } public static class Processor<I extends Iface> extends FateService.Processor<I> implements org.apache.thrift.TProcessor { @@ -1241,6 +1311,7 @@ import org.slf4j.LoggerFactory; processMap.put("reportSplitExtent", new reportSplitExtent()); processMap.put("reportTabletStatus", new reportTabletStatus()); processMap.put("getActiveTservers", new getActiveTservers()); + processMap.put("getDelegationToken", new getDelegationToken()); return processMap; } @@ -1627,6 +1698,30 @@ import org.slf4j.LoggerFactory; } } + public static class getDelegationToken<I extends Iface> extends org.apache.thrift.ProcessFunction<I, getDelegationToken_args> { + public getDelegationToken() { + super("getDelegationToken"); + } + + public getDelegationToken_args getEmptyArgsInstance() { + return new getDelegationToken_args(); + } + + protected boolean isOneway() { + return false; + } + + public getDelegationToken_result getResult(I iface, getDelegationToken_args args) throws org.apache.thrift.TException { + getDelegationToken_result result = new getDelegationToken_result(); + try { + result.success = iface.getDelegationToken(args.tinfo, args.credentials, args.cfg); + } catch (org.apache.accumulo.core.client.impl.thrift.ThriftSecurityException sec) { + result.sec = sec; + } + return result; + } + } + } public static class AsyncProcessor<I extends AsyncIface> extends FateService.AsyncProcessor<I> { @@ -1656,6 +1751,7 @@ import org.slf4j.LoggerFactory; processMap.put("reportSplitExtent", new reportSplitExtent()); processMap.put("reportTabletStatus", new reportTabletStatus()); processMap.put("getActiveTservers", new getActiveTservers()); + processMap.put("getDelegationToken", new getDelegationToken()); return processMap; } @@ -2527,6 +2623,63 @@ import org.slf4j.LoggerFactory; } } + public static class getDelegationToken<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, getDelegationToken_args, org.apache.accumulo.core.security.thrift.TDelegationToken> { + public getDelegationToken() { + super("getDelegationToken"); + } + + public getDelegationToken_args getEmptyArgsInstance() { + return new getDelegationToken_args(); + } + + public AsyncMethodCallback<org.apache.accumulo.core.security.thrift.TDelegationToken> getResultHandler(final AsyncFrameBuffer fb, final int seqid) { + final org.apache.thrift.AsyncProcessFunction fcall = this; + return new AsyncMethodCallback<org.apache.accumulo.core.security.thrift.TDelegationToken>() { + public void onComplete(org.apache.accumulo.core.security.thrift.TDelegationToken o) { + getDelegationToken_result result = new getDelegationToken_result(); + result.success = o; + try { + fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid); + return; + } catch (Exception e) { + LOGGER.error("Exception writing to internal frame buffer", e); + } + fb.close(); + } + public void onError(Exception e) { + byte msgType = org.apache.thrift.protocol.TMessageType.REPLY; + org.apache.thrift.TBase msg; + getDelegationToken_result result = new getDelegationToken_result(); + if (e instanceof org.apache.accumulo.core.client.impl.thrift.ThriftSecurityException) { + result.sec = (org.apache.accumulo.core.client.impl.thrift.ThriftSecurityException) e; + result.setSecIsSet(true); + msg = result; + } + else + { + msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION; + msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage()); + } + try { + fcall.sendResponse(fb,msg,msgType,seqid); + return; + } catch (Exception ex) { + LOGGER.error("Exception writing to internal frame buffer", ex); + } + fb.close(); + } + }; + } + + protected boolean isOneway() { + return false; + } + + public void start(I iface, getDelegationToken_args args, org.apache.thrift.async.AsyncMethodCallback<org.apache.accumulo.core.security.thrift.TDelegationToken> resultHandler) throws TException { + iface.getDelegationToken(args.tinfo, args.credentials, args.cfg,resultHandler); + } + } + } public static class initiateFlush_args implements org.apache.thrift.TBase<initiateFlush_args, initiateFlush_args._Fields>, java.io.Serializable, Cloneable, Comparable<initiateFlush_args> { @@ -18540,4 +18693,1034 @@ import org.slf4j.LoggerFactory; } + public static class getDelegationToken_args implements org.apache.thrift.TBase<getDelegationToken_args, getDelegationToken_args._Fields>, java.io.Serializable, Cloneable, Comparable<getDelegationToken_args> { + private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getDelegationToken_args"); + + private static final org.apache.thrift.protocol.TField TINFO_FIELD_DESC = new org.apache.thrift.protocol.TField("tinfo", org.apache.thrift.protocol.TType.STRUCT, (short)1); + private static final org.apache.thrift.protocol.TField CREDENTIALS_FIELD_DESC = new org.apache.thrift.protocol.TField("credentials", org.apache.thrift.protocol.TType.STRUCT, (short)2); + private static final org.apache.thrift.protocol.TField CFG_FIELD_DESC = new org.apache.thrift.protocol.TField("cfg", org.apache.thrift.protocol.TType.STRUCT, (short)3); + + private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>(); + static { + schemes.put(StandardScheme.class, new getDelegationToken_argsStandardSchemeFactory()); + schemes.put(TupleScheme.class, new getDelegationToken_argsTupleSchemeFactory()); + } + + public org.apache.accumulo.core.trace.thrift.TInfo tinfo; // required + public org.apache.accumulo.core.security.thrift.TCredentials credentials; // required + public org.apache.accumulo.core.security.thrift.TDelegationTokenConfig cfg; // required + + /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */ + public enum _Fields implements org.apache.thrift.TFieldIdEnum { + TINFO((short)1, "tinfo"), + CREDENTIALS((short)2, "credentials"), + CFG((short)3, "cfg"); + + private static final Map<String, _Fields> byName = new HashMap<String, _Fields>(); + + static { + for (_Fields field : EnumSet.allOf(_Fields.class)) { + byName.put(field.getFieldName(), field); + } + } + + /** + * Find the _Fields constant that matches fieldId, or null if its not found. + */ + public static _Fields findByThriftId(int fieldId) { + switch(fieldId) { + case 1: // TINFO + return TINFO; + case 2: // CREDENTIALS + return CREDENTIALS; + case 3: // CFG + return CFG; + default: + return null; + } + } + + /** + * Find the _Fields constant that matches fieldId, throwing an exception + * if it is not found. + */ + public static _Fields findByThriftIdOrThrow(int fieldId) { + _Fields fields = findByThriftId(fieldId); + if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!"); + return fields; + } + + /** + * Find the _Fields constant that matches name, or null if its not found. + */ + public static _Fields findByName(String name) { + return byName.get(name); + } + + private final short _thriftId; + private final String _fieldName; + + _Fields(short thriftId, String fieldName) { + _thriftId = thriftId; + _fieldName = fieldName; + } + + public short getThriftFieldId() { + return _thriftId; + } + + public String getFieldName() { + return _fieldName; + } + } + + // isset id assignments + public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap; + static { + Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class); + tmpMap.put(_Fields.TINFO, new org.apache.thrift.meta_data.FieldMetaData("tinfo", org.apache.thrift.TFieldRequirementType.DEFAULT, + new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.accumulo.core.trace.thrift.TInfo.class))); + tmpMap.put(_Fields.CREDENTIALS, new org.apache.thrift.meta_data.FieldMetaData("credentials", org.apache.thrift.TFieldRequirementType.DEFAULT, + new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.accumulo.core.security.thrift.TCredentials.class))); + tmpMap.put(_Fields.CFG, new org.apache.thrift.meta_data.FieldMetaData("cfg", org.apache.thrift.TFieldRequirementType.DEFAULT, + new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.accumulo.core.security.thrift.TDelegationTokenConfig.class))); + metaDataMap = Collections.unmodifiableMap(tmpMap); + org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getDelegationToken_args.class, metaDataMap); + } + + public getDelegationToken_args() { + } + + public getDelegationToken_args( + org.apache.accumulo.core.trace.thrift.TInfo tinfo, + org.apache.accumulo.core.security.thrift.TCredentials credentials, + org.apache.accumulo.core.security.thrift.TDelegationTokenConfig cfg) + { + this(); + this.tinfo = tinfo; + this.credentials = credentials; + this.cfg = cfg; + } + + /** + * Performs a deep copy on <i>other</i>. + */ + public getDelegationToken_args(getDelegationToken_args other) { + if (other.isSetTinfo()) { + this.tinfo = new org.apache.accumulo.core.trace.thrift.TInfo(other.tinfo); + } + if (other.isSetCredentials()) { + this.credentials = new org.apache.accumulo.core.security.thrift.TCredentials(other.credentials); + } + if (other.isSetCfg()) { + this.cfg = new org.apache.accumulo.core.security.thrift.TDelegationTokenConfig(other.cfg); + } + } + + public getDelegationToken_args deepCopy() { + return new getDelegationToken_args(this); + } + + @Override + public void clear() { + this.tinfo = null; + this.credentials = null; + this.cfg = null; + } + + public org.apache.accumulo.core.trace.thrift.TInfo getTinfo() { + return this.tinfo; + } + + public getDelegationToken_args setTinfo(org.apache.accumulo.core.trace.thrift.TInfo tinfo) { + this.tinfo = tinfo; + return this; + } + + public void unsetTinfo() { + this.tinfo = null; + } + + /** Returns true if field tinfo is set (has been assigned a value) and false otherwise */ + public boolean isSetTinfo() { + return this.tinfo != null; + } + + public void setTinfoIsSet(boolean value) { + if (!value) { + this.tinfo = null; + } + } + + public org.apache.accumulo.core.security.thrift.TCredentials getCredentials() { + return this.credentials; + } + + public getDelegationToken_args setCredentials(org.apache.accumulo.core.security.thrift.TCredentials credentials) { + this.credentials = credentials; + return this; + } + + public void unsetCredentials() { + this.credentials = null; + } + + /** Returns true if field credentials is set (has been assigned a value) and false otherwise */ + public boolean isSetCredentials() { + return this.credentials != null; + } + + public void setCredentialsIsSet(boolean value) { + if (!value) { + this.credentials = null; + } + } + + public org.apache.accumulo.core.security.thrift.TDelegationTokenConfig getCfg() { + return this.cfg; + } + + public getDelegationToken_args setCfg(org.apache.accumulo.core.security.thrift.TDelegationTokenConfig cfg) { + this.cfg = cfg; + return this; + } + + public void unsetCfg() { + this.cfg = null; + } + + /** Returns true if field cfg is set (has been assigned a value) and false otherwise */ + public boolean isSetCfg() { + return this.cfg != null; + } + + public void setCfgIsSet(boolean value) { + if (!value) { + this.cfg = null; + } + } + + public void setFieldValue(_Fields field, Object value) { + switch (field) { + case TINFO: + if (value == null) { + unsetTinfo(); + } else { + setTinfo((org.apache.accumulo.core.trace.thrift.TInfo)value); + } + break; + + case CREDENTIALS: + if (value == null) { + unsetCredentials(); + } else { + setCredentials((org.apache.accumulo.core.security.thrift.TCredentials)value); + } + break; + + case CFG: + if (value == null) { + unsetCfg(); + } else { + setCfg((org.apache.accumulo.core.security.thrift.TDelegationTokenConfig)value); + } + break; + + } + } + + public Object getFieldValue(_Fields field) { + switch (field) { + case TINFO: + return getTinfo(); + + case CREDENTIALS: + return getCredentials(); + + case CFG: + return getCfg(); + + } + throw new IllegalStateException(); + } + + /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */ + public boolean isSet(_Fields field) { + if (field == null) { + throw new IllegalArgumentException(); + } + + switch (field) { + case TINFO: + return isSetTinfo(); + case CREDENTIALS: + return isSetCredentials(); + case CFG: + return isSetCfg(); + } + throw new IllegalStateException(); + } + + @Override + public boolean equals(Object that) { + if (that == null) + return false; + if (that instanceof getDelegationToken_args) + return this.equals((getDelegationToken_args)that); + return false; + } + + public boolean equals(getDelegationToken_args that) { + if (that == null) + return false; + + boolean this_present_tinfo = true && this.isSetTinfo(); + boolean that_present_tinfo = true && that.isSetTinfo(); + if (this_present_tinfo || that_present_tinfo) { + if (!(this_present_tinfo && that_present_tinfo)) + return false; + if (!this.tinfo.equals(that.tinfo)) + return false; + } + + boolean this_present_credentials = true && this.isSetCredentials(); + boolean that_present_credentials = true && that.isSetCredentials(); + if (this_present_credentials || that_present_credentials) { + if (!(this_present_credentials && that_present_credentials)) + return false; + if (!this.credentials.equals(that.credentials)) + return false; + } + + boolean this_present_cfg = true && this.isSetCfg(); + boolean that_present_cfg = true && that.isSetCfg(); + if (this_present_cfg || that_present_cfg) { + if (!(this_present_cfg && that_present_cfg)) + return false; + if (!this.cfg.equals(that.cfg)) + return false; + } + + return true; + } + + @Override + public int hashCode() { + return 0; + } + + @Override + public int compareTo(getDelegationToken_args other) { + if (!getClass().equals(other.getClass())) { + return getClass().getName().compareTo(other.getClass().getName()); + } + + int lastComparison = 0; + + lastComparison = Boolean.valueOf(isSetTinfo()).compareTo(other.isSetTinfo()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetTinfo()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.tinfo, other.tinfo); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetCredentials()).compareTo(other.isSetCredentials()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetCredentials()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.credentials, other.credentials); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetCfg()).compareTo(other.isSetCfg()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetCfg()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.cfg, other.cfg); + if (lastComparison != 0) { + return lastComparison; + } + } + return 0; + } + + public _Fields fieldForId(int fieldId) { + return _Fields.findByThriftId(fieldId); + } + + public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException { + schemes.get(iprot.getScheme()).getScheme().read(iprot, this); + } + + public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException { + schemes.get(oprot.getScheme()).getScheme().write(oprot, this); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder("getDelegationToken_args("); + boolean first = true; + + sb.append("tinfo:"); + if (this.tinfo == null) { + sb.append("null"); + } else { + sb.append(this.tinfo); + } + first = false; + if (!first) sb.append(", "); + sb.append("credentials:"); + if (this.credentials == null) { + sb.append("null"); + } else { + sb.append(this.credentials); + } + first = false; + if (!first) sb.append(", "); + sb.append("cfg:"); + if (this.cfg == null) { + sb.append("null"); + } else { + sb.append(this.cfg); + } + first = false; + sb.append(")"); + return sb.toString(); + } + + public void validate() throws org.apache.thrift.TException { + // check for required fields + // check for sub-struct validity + if (tinfo != null) { + tinfo.validate(); + } + if (credentials != null) { + credentials.validate(); + } + if (cfg != null) { + cfg.validate(); + } + } + + private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException { + try { + write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out))); + } catch (org.apache.thrift.TException te) { + throw new java.io.IOException(te); + } + } + + private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException { + try { + read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in))); + } catch (org.apache.thrift.TException te) { + throw new java.io.IOException(te); + } + } + + private static class getDelegationToken_argsStandardSchemeFactory implements SchemeFactory { + public getDelegationToken_argsStandardScheme getScheme() { + return new getDelegationToken_argsStandardScheme(); + } + } + + private static class getDelegationToken_argsStandardScheme extends StandardScheme<getDelegationToken_args> { + + public void read(org.apache.thrift.protocol.TProtocol iprot, getDelegationToken_args struct) throws org.apache.thrift.TException { + org.apache.thrift.protocol.TField schemeField; + iprot.readStructBegin(); + while (true) + { + schemeField = iprot.readFieldBegin(); + if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { + break; + } + switch (schemeField.id) { + case 1: // TINFO + if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) { + struct.tinfo = new org.apache.accumulo.core.trace.thrift.TInfo(); + struct.tinfo.read(iprot); + struct.setTinfoIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + case 2: // CREDENTIALS + if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) { + struct.credentials = new org.apache.accumulo.core.security.thrift.TCredentials(); + struct.credentials.read(iprot); + struct.setCredentialsIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + case 3: // CFG + if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) { + struct.cfg = new org.apache.accumulo.core.security.thrift.TDelegationTokenConfig(); + struct.cfg.read(iprot); + struct.setCfgIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + default: + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + iprot.readFieldEnd(); + } + iprot.readStructEnd(); + + // check for required fields of primitive type, which can't be checked in the validate method + struct.validate(); + } + + public void write(org.apache.thrift.protocol.TProtocol oprot, getDelegationToken_args struct) throws org.apache.thrift.TException { + struct.validate(); + + oprot.writeStructBegin(STRUCT_DESC); + if (struct.tinfo != null) { + oprot.writeFieldBegin(TINFO_FIELD_DESC); + struct.tinfo.write(oprot); + oprot.writeFieldEnd(); + } + if (struct.credentials != null) { + oprot.writeFieldBegin(CREDENTIALS_FIELD_DESC); + struct.credentials.write(oprot); + oprot.writeFieldEnd(); + } + if (struct.cfg != null) { + oprot.writeFieldBegin(CFG_FIELD_DESC); + struct.cfg.write(oprot); + oprot.writeFieldEnd(); + } + oprot.writeFieldStop(); + oprot.writeStructEnd(); + } + + } + + private static class getDelegationToken_argsTupleSchemeFactory implements SchemeFactory { + public getDelegationToken_argsTupleScheme getScheme() { + return new getDelegationToken_argsTupleScheme(); + } + } + + private static class getDelegationToken_argsTupleScheme extends TupleScheme<getDelegationToken_args> { + + @Override + public void write(org.apache.thrift.protocol.TProtocol prot, getDelegationToken_args struct) throws org.apache.thrift.TException { + TTupleProtocol oprot = (TTupleProtocol) prot; + BitSet optionals = new BitSet(); + if (struct.isSetTinfo()) { + optionals.set(0); + } + if (struct.isSetCredentials()) { + optionals.set(1); + } + if (struct.isSetCfg()) { + optionals.set(2); + } + oprot.writeBitSet(optionals, 3); + if (struct.isSetTinfo()) { + struct.tinfo.write(oprot); + } + if (struct.isSetCredentials()) { + struct.credentials.write(oprot); + } + if (struct.isSetCfg()) { + struct.cfg.write(oprot); + } + } + + @Override + public void read(org.apache.thrift.protocol.TProtocol prot, getDelegationToken_args struct) throws org.apache.thrift.TException { + TTupleProtocol iprot = (TTupleProtocol) prot; + BitSet incoming = iprot.readBitSet(3); + if (incoming.get(0)) { + struct.tinfo = new org.apache.accumulo.core.trace.thrift.TInfo(); + struct.tinfo.read(iprot); + struct.setTinfoIsSet(true); + } + if (incoming.get(1)) { + struct.credentials = new org.apache.accumulo.core.security.thrift.TCredentials(); + struct.credentials.read(iprot); + struct.setCredentialsIsSet(true); + } + if (incoming.get(2)) { + struct.cfg = new org.apache.accumulo.core.security.thrift.TDelegationTokenConfig(); + struct.cfg.read(iprot); + struct.setCfgIsSet(true); + } + } + } + + } + + public static class getDelegationToken_result implements org.apache.thrift.TBase<getDelegationToken_result, getDelegationToken_result._Fields>, java.io.Serializable, Cloneable, Comparable<getDelegationToken_result> { + private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getDelegationToken_result"); + + private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.STRUCT, (short)0); + private static final org.apache.thrift.protocol.TField SEC_FIELD_DESC = new org.apache.thrift.protocol.TField("sec", org.apache.thrift.protocol.TType.STRUCT, (short)1); + + private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>(); + static { + schemes.put(StandardScheme.class, new getDelegationToken_resultStandardSchemeFactory()); + schemes.put(TupleScheme.class, new getDelegationToken_resultTupleSchemeFactory()); + } + + public org.apache.accumulo.core.security.thrift.TDelegationToken success; // required + public org.apache.accumulo.core.client.impl.thrift.ThriftSecurityException sec; // required + + /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */ + public enum _Fields implements org.apache.thrift.TFieldIdEnum { + SUCCESS((short)0, "success"), + SEC((short)1, "sec"); + + private static final Map<String, _Fields> byName = new HashMap<String, _Fields>(); + + static { + for (_Fields field : EnumSet.allOf(_Fields.class)) { + byName.put(field.getFieldName(), field); + } + } + + /** + * Find the _Fields constant that matches fieldId, or null if its not found. + */ + public static _Fields findByThriftId(int fieldId) { + switch(fieldId) { + case 0: // SUCCESS + return SUCCESS; + case 1: // SEC + return SEC; + default: + return null; + } + } + + /** + * Find the _Fields constant that matches fieldId, throwing an exception + * if it is not found. + */ + public static _Fields findByThriftIdOrThrow(int fieldId) { + _Fields fields = findByThriftId(fieldId); + if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!"); + return fields; + } + + /** + * Find the _Fields constant that matches name, or null if its not found. + */ + public static _Fields findByName(String name) { + return byName.get(name); + } + + private final short _thriftId; + private final String _fieldName; + + _Fields(short thriftId, String fieldName) { + _thriftId = thriftId; + _fieldName = fieldName; + } + + public short getThriftFieldId() { + return _thriftId; + } + + public String getFieldName() { + return _fieldName; + } + } + + // isset id assignments + public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap; + static { + Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class); + tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, + new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.accumulo.core.security.thrift.TDelegationToken.class))); + tmpMap.put(_Fields.SEC, new org.apache.thrift.meta_data.FieldMetaData("sec", org.apache.thrift.TFieldRequirementType.DEFAULT, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT))); + metaDataMap = Collections.unmodifiableMap(tmpMap); + org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getDelegationToken_result.class, metaDataMap); + } + + public getDelegationToken_result() { + } + + public getDelegationToken_result( + org.apache.accumulo.core.security.thrift.TDelegationToken success, + org.apache.accumulo.core.client.impl.thrift.ThriftSecurityException sec) + { + this(); + this.success = success; + this.sec = sec; + } + + /** + * Performs a deep copy on <i>other</i>. + */ + public getDelegationToken_result(getDelegationToken_result other) { + if (other.isSetSuccess()) { + this.success = new org.apache.accumulo.core.security.thrift.TDelegationToken(other.success); + } + if (other.isSetSec()) { + this.sec = new org.apache.accumulo.core.client.impl.thrift.ThriftSecurityException(other.sec); + } + } + + public getDelegationToken_result deepCopy() { + return new getDelegationToken_result(this); + } + + @Override + public void clear() { + this.success = null; + this.sec = null; + } + + public org.apache.accumulo.core.security.thrift.TDelegationToken getSuccess() { + return this.success; + } + + public getDelegationToken_result setSuccess(org.apache.accumulo.core.security.thrift.TDelegationToken success) { + this.success = success; + return this; + } + + public void unsetSuccess() { + this.success = null; + } + + /** Returns true if field success is set (has been assigned a value) and false otherwise */ + public boolean isSetSuccess() { + return this.success != null; + } + + public void setSuccessIsSet(boolean value) { + if (!value) { + this.success = null; + } + } + + public org.apache.accumulo.core.client.impl.thrift.ThriftSecurityException getSec() { + return this.sec; + } + + public getDelegationToken_result setSec(org.apache.accumulo.core.client.impl.thrift.ThriftSecurityException sec) { + this.sec = sec; + return this; + } + + public void unsetSec() { + this.sec = null; + } + + /** Returns true if field sec is set (has been assigned a value) and false otherwise */ + public boolean isSetSec() { + return this.sec != null; + } + + public void setSecIsSet(boolean value) { + if (!value) { + this.sec = null; + } + } + + public void setFieldValue(_Fields field, Object value) { + switch (field) { + case SUCCESS: + if (value == null) { + unsetSuccess(); + } else { + setSuccess((org.apache.accumulo.core.security.thrift.TDelegationToken)value); + } + break; + + case SEC: + if (value == null) { + unsetSec(); + } else { + setSec((org.apache.accumulo.core.client.impl.thrift.ThriftSecurityException)value); + } + break; + + } + } + + public Object getFieldValue(_Fields field) { + switch (field) { + case SUCCESS: + return getSuccess(); + + case SEC: + return getSec(); + + } + throw new IllegalStateException(); + } + + /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */ + public boolean isSet(_Fields field) { + if (field == null) { + throw new IllegalArgumentException(); + } + + switch (field) { + case SUCCESS: + return isSetSuccess(); + case SEC: + return isSetSec(); + } + throw new IllegalStateException(); + } + + @Override + public boolean equals(Object that) { + if (that == null) + return false; + if (that instanceof getDelegationToken_result) + return this.equals((getDelegationToken_result)that); + return false; + } + + public boolean equals(getDelegationToken_result that) { + if (that == null) + return false; + + boolean this_present_success = true && this.isSetSuccess(); + boolean that_present_success = true && that.isSetSuccess(); + if (this_present_success || that_present_success) { + if (!(this_present_success && that_present_success)) + return false; + if (!this.success.equals(that.success)) + return false; + } + + boolean this_present_sec = true && this.isSetSec(); + boolean that_present_sec = true && that.isSetSec(); + if (this_present_sec || that_present_sec) { + if (!(this_present_sec && that_present_sec)) + return false; + if (!this.sec.equals(that.sec)) + return false; + } + + return true; + } + + @Override + public int hashCode() { + return 0; + } + + @Override + public int compareTo(getDelegationToken_result other) { + if (!getClass().equals(other.getClass())) { + return getClass().getName().compareTo(other.getClass().getName()); + } + + int lastComparison = 0; + + lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetSuccess()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetSec()).compareTo(other.isSetSec()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetSec()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.sec, other.sec); + if (lastComparison != 0) { + return lastComparison; + } + } + return 0; + } + + public _Fields fieldForId(int fieldId) { + return _Fields.findByThriftId(fieldId); + } + + public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException { + schemes.get(iprot.getScheme()).getScheme().read(iprot, this); + } + + public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException { + schemes.get(oprot.getScheme()).getScheme().write(oprot, this); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder("getDelegationToken_result("); + boolean first = true; + + sb.append("success:"); + if (this.success == null) { + sb.append("null"); + } else { + sb.append(this.success); + } + first = false; + if (!first) sb.append(", "); + sb.append("sec:"); + if (this.sec == null) { + sb.append("null"); + } else { + sb.append(this.sec); + } + first = false; + sb.append(")"); + return sb.toString(); + } + + public void validate() throws org.apache.thrift.TException { + // check for required fields + // check for sub-struct validity + if (success != null) { + success.validate(); + } + } + + private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException { + try { + write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out))); + } catch (org.apache.thrift.TException te) { + throw new java.io.IOException(te); + } + } + + private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException { + try { + read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in))); + } catch (org.apache.thrift.TException te) { + throw new java.io.IOException(te); + } + } + + private static class getDelegationToken_resultStandardSchemeFactory implements SchemeFactory { + public getDelegationToken_resultStandardScheme getScheme() { + return new getDelegationToken_resultStandardScheme(); + } + } + + private static class getDelegationToken_resultStandardScheme extends StandardScheme<getDelegationToken_result> { + + public void read(org.apache.thrift.protocol.TProtocol iprot, getDelegationToken_result struct) throws org.apache.thrift.TException { + org.apache.thrift.protocol.TField schemeField; + iprot.readStructBegin(); + while (true) + { + schemeField = iprot.readFieldBegin(); + if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { + break; + } + switch (schemeField.id) { + case 0: // SUCCESS + if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) { + struct.success = new org.apache.accumulo.core.security.thrift.TDelegationToken(); + struct.success.read(iprot); + struct.setSuccessIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + case 1: // SEC + if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) { + struct.sec = new org.apache.accumulo.core.client.impl.thrift.ThriftSecurityException(); + struct.sec.read(iprot); + struct.setSecIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + default: + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + iprot.readFieldEnd(); + } + iprot.readStructEnd(); + + // check for required fields of primitive type, which can't be checked in the validate method + struct.validate(); + } + + public void write(org.apache.thrift.protocol.TProtocol oprot, getDelegationToken_result struct) throws org.apache.thrift.TException { + struct.validate(); + + oprot.writeStructBegin(STRUCT_DESC); + if (struct.success != null) { + oprot.writeFieldBegin(SUCCESS_FIELD_DESC); + struct.success.write(oprot); + oprot.writeFieldEnd(); + } + if (struct.sec != null) { + oprot.writeFieldBegin(SEC_FIELD_DESC); + struct.sec.write(oprot); + oprot.writeFieldEnd(); + } + oprot.writeFieldStop(); + oprot.writeStructEnd(); + } + + } + + private static class getDelegationToken_resultTupleSchemeFactory implements SchemeFactory { + public getDelegationToken_resultTupleScheme getScheme() { + return new getDelegationToken_resultTupleScheme(); + } + } + + private static class getDelegationToken_resultTupleScheme extends TupleScheme<getDelegationToken_result> { + + @Override + public void write(org.apache.thrift.protocol.TProtocol prot, getDelegationToken_result struct) throws org.apache.thrift.TException { + TTupleProtocol oprot = (TTupleProtocol) prot; + BitSet optionals = new BitSet(); + if (struct.isSetSuccess()) { + optionals.set(0); + } + if (struct.isSetSec()) { + optionals.set(1); + } + oprot.writeBitSet(optionals, 2); + if (struct.isSetSuccess()) { + struct.success.write(oprot); + } + if (struct.isSetSec()) { + struct.sec.write(oprot); + } + } + + @Override + public void read(org.apache.thrift.protocol.TProtocol prot, getDelegationToken_result struct) throws org.apache.thrift.TException { + TTupleProtocol iprot = (TTupleProtocol) prot; + BitSet incoming = iprot.readBitSet(2); + if (incoming.get(0)) { + struct.success = new org.apache.accumulo.core.security.thrift.TDelegationToken(); + struct.success.read(iprot); + struct.setSuccessIsSet(true); + } + if (incoming.get(1)) { + struct.sec = new org.apache.accumulo.core.client.impl.thrift.ThriftSecurityException(); + struct.sec.read(iprot); + struct.setSecIsSet(true); + } + } + } + + } + }
http://git-wip-us.apache.org/repos/asf/accumulo/blob/2c983317/core/src/main/java/org/apache/accumulo/core/rpc/SaslClientDigestCallbackHandler.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/accumulo/core/rpc/SaslClientDigestCallbackHandler.java b/core/src/main/java/org/apache/accumulo/core/rpc/SaslClientDigestCallbackHandler.java new file mode 100644 index 0000000..18dd7e1 --- /dev/null +++ b/core/src/main/java/org/apache/accumulo/core/rpc/SaslClientDigestCallbackHandler.java @@ -0,0 +1,114 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.accumulo.core.rpc; + +import static com.google.common.base.Preconditions.checkNotNull; + +import java.util.Arrays; + +import javax.security.auth.callback.Callback; +import javax.security.auth.callback.NameCallback; +import javax.security.auth.callback.PasswordCallback; +import javax.security.auth.callback.UnsupportedCallbackException; +import javax.security.sasl.RealmCallback; +import javax.security.sasl.RealmChoiceCallback; + +import org.apache.accumulo.core.client.security.tokens.DelegationToken; +import org.apache.commons.lang.builder.HashCodeBuilder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Client-side callbackhandler for sasl authentication which is the client-side sibling to the server-side {@link SaslDigestCallbackHandler}. Encoding of name, + * password and realm information must be consistent across the pair. + */ +public class SaslClientDigestCallbackHandler extends SaslDigestCallbackHandler { + private static final Logger log = LoggerFactory.getLogger(SaslClientDigestCallbackHandler.class); + private static final String NAME = SaslClientDigestCallbackHandler.class.getSimpleName(); + + private final String userName; + private final char[] userPassword; + + public SaslClientDigestCallbackHandler(DelegationToken token) { + checkNotNull(token); + this.userName = encodeIdentifier(token.getIdentifier().getBytes()); + this.userPassword = encodePassword(token.getPassword()); + } + + public SaslClientDigestCallbackHandler(String userName, char[] userPassword) { + checkNotNull(userName); + checkNotNull(userPassword); + this.userName = userName; + this.userPassword = userPassword; + } + + @Override + public void handle(Callback[] callbacks) throws UnsupportedCallbackException { + NameCallback nc = null; + PasswordCallback pc = null; + RealmCallback rc = null; + for (Callback callback : callbacks) { + if (callback instanceof RealmChoiceCallback) { + continue; + } else if (callback instanceof NameCallback) { + nc = (NameCallback) callback; + } else if (callback instanceof PasswordCallback) { + pc = (PasswordCallback) callback; + } else if (callback instanceof RealmCallback) { + rc = (RealmCallback) callback; + } else { + throw new UnsupportedCallbackException(callback, "Unrecognized SASL client callback"); + } + } + if (nc != null) { + log.debug("SASL client callback: setting username: {}", userName); + nc.setName(userName); + } + if (pc != null) { + log.debug("SASL client callback: setting userPassword"); + pc.setPassword(userPassword); + } + if (rc != null) { + log.debug("SASL client callback: setting realm: {}", rc.getDefaultText()); + rc.setText(rc.getDefaultText()); + } + } + + @Override + public String toString() { + return NAME; + } + + @Override + public int hashCode() { + HashCodeBuilder hcb = new HashCodeBuilder(41, 47); + hcb.append(userName).append(userPassword); + return hcb.toHashCode(); + } + + @Override + public boolean equals(Object o) { + if (null == o) { + return false; + } + if (o instanceof SaslClientDigestCallbackHandler) { + SaslClientDigestCallbackHandler other = (SaslClientDigestCallbackHandler) o; + return userName.equals(other.userName) && Arrays.equals(userPassword, other.userPassword); + } + return false; + } +} http://git-wip-us.apache.org/repos/asf/accumulo/blob/2c983317/core/src/main/java/org/apache/accumulo/core/rpc/SaslConnectionParams.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/accumulo/core/rpc/SaslConnectionParams.java b/core/src/main/java/org/apache/accumulo/core/rpc/SaslConnectionParams.java index e067e23..10438de 100644 --- a/core/src/main/java/org/apache/accumulo/core/rpc/SaslConnectionParams.java +++ b/core/src/main/java/org/apache/accumulo/core/rpc/SaslConnectionParams.java @@ -16,6 +16,8 @@ */ package org.apache.accumulo.core.rpc; +import static com.google.common.base.Preconditions.checkNotNull; + import java.io.IOException; import java.util.Collections; import java.util.HashMap; @@ -23,10 +25,14 @@ import java.util.HashSet; import java.util.Map; import java.util.Map.Entry; +import javax.security.auth.callback.CallbackHandler; import javax.security.sasl.Sasl; import org.apache.accumulo.core.client.ClientConfiguration; import org.apache.accumulo.core.client.ClientConfiguration.ClientProperty; +import org.apache.accumulo.core.client.security.tokens.AuthenticationToken; +import org.apache.accumulo.core.client.security.tokens.DelegationToken; +import org.apache.accumulo.core.client.security.tokens.KerberosToken; import org.apache.accumulo.core.conf.AccumuloConfiguration; import org.apache.accumulo.core.conf.Property; import org.apache.commons.configuration.MapConfiguration; @@ -79,6 +85,34 @@ public class SaslConnectionParams { } } + /** + * The SASL mechanism to use for authentication + */ + public enum SaslMechanism { + GSSAPI("GSSAPI"), // Kerberos + DIGEST_MD5("DIGEST-MD5"); // Delegation Tokens + + private final String mechanismName; + + private SaslMechanism(String mechanismName) { + this.mechanismName = mechanismName; + } + + public String getMechanismName() { + return mechanismName; + } + + public static SaslMechanism get(String mechanismName) { + if (GSSAPI.mechanismName.equals(mechanismName)) { + return GSSAPI; + } else if (DIGEST_MD5.mechanismName.equals(mechanismName)) { + return DIGEST_MD5; + } + + throw new IllegalArgumentException("No value for " + mechanismName); + } + } + private static String defaultRealm; static { @@ -90,25 +124,47 @@ public class SaslConnectionParams { } } - private String principal; - private QualityOfProtection qop; - private String kerberosServerPrimary; - private final Map<String,String> saslProperties; - - private SaslConnectionParams() { - saslProperties = new HashMap<>(); - } + protected String principal; + protected QualityOfProtection qop; + protected String kerberosServerPrimary; + protected SaslMechanism mechanism; + protected CallbackHandler callbackHandler; + protected final Map<String,String> saslProperties; /** * Generate an {@link SaslConnectionParams} instance given the provided {@link AccumuloConfiguration}. The provided configuration is converted into a * {@link ClientConfiguration}, ignoring any properties which are not {@link ClientProperty}s. If SASL is not being used, a null object will be returned. * Callers should strive to use {@link #forConfig(ClientConfiguration)}; server processes are the only intended consumers of this method. * - * @param conf - * The configuration for clients to communicate with Accumulo - * @return An {@link SaslConnectionParams} instance or null if SASL is not enabled */ - public static SaslConnectionParams forConfig(AccumuloConfiguration conf) { + public SaslConnectionParams(AccumuloConfiguration conf, AuthenticationToken token) { + this(new ClientConfiguration(new MapConfiguration(getProperties(conf))), token); + } + + public SaslConnectionParams(ClientConfiguration conf, AuthenticationToken token) { + checkNotNull(conf, "Configuration was null"); + checkNotNull(token, "AuthenticationToken was null"); + + saslProperties = new HashMap<>(); + updatePrincipalFromUgi(); + updateFromConfiguration(conf); + updateFromToken(token); + } + + protected void updateFromToken(AuthenticationToken token) { + if (token instanceof KerberosToken) { + mechanism = SaslMechanism.GSSAPI; + // No callbackhandlers necessary for GSSAPI + callbackHandler = null; + } else if (token instanceof DelegationToken) { + mechanism = SaslMechanism.DIGEST_MD5; + callbackHandler = new SaslClientDigestCallbackHandler((DelegationToken) token); + } else { + throw new IllegalArgumentException("Cannot determine SASL mechanism for token class: " + token.getClass()); + } + } + + protected static Map<String,String> getProperties(AccumuloConfiguration conf) { final Map<String,String> clientProperties = new HashMap<>(); // Servers will only have the full principal in their configuration -- parse the @@ -136,25 +192,10 @@ public class SaslConnectionParams { } } - ClientConfiguration clientConf = new ClientConfiguration(new MapConfiguration(clientProperties)); - return forConfig(clientConf); + return clientProperties; } - /** - * Generate an {@link SaslConnectionParams} instance given the provided {@link ClientConfiguration}. If SASL is not being used, a null object will be - * returned. - * - * @param conf - * The configuration for clients to communicate with Accumulo - * @return An {@link SaslConnectionParams} instance or null if SASL is not enabled - */ - public static SaslConnectionParams forConfig(ClientConfiguration conf) { - if (!Boolean.parseBoolean(conf.get(ClientProperty.INSTANCE_RPC_SASL_ENABLED))) { - return null; - } - - SaslConnectionParams params = new SaslConnectionParams(); - + protected void updatePrincipalFromUgi() { // Ensure we're using Kerberos auth for Hadoop UGI if (!UserGroupInformation.isSecurityEnabled()) { throw new RuntimeException("Cannot use SASL if Hadoop security is not enabled"); @@ -169,22 +210,23 @@ public class SaslConnectionParams { } // The full name is our principal - params.principal = currentUser.getUserName(); - if (null == params.principal) { + this.principal = currentUser.getUserName(); + if (null == this.principal) { throw new RuntimeException("Got null username from " + currentUser); } + } + + protected void updateFromConfiguration(ClientConfiguration conf) { // Get the quality of protection to use final String qopValue = conf.get(ClientProperty.RPC_SASL_QOP); - params.qop = QualityOfProtection.get(qopValue); + this.qop = QualityOfProtection.get(qopValue); // Add in the SASL properties to a map so we don't have to repeatedly construct this map - params.saslProperties.put(Sasl.QOP, params.qop.getQuality()); + this.saslProperties.put(Sasl.QOP, this.qop.getQuality()); // The primary from the KRB principal on each server (e.g. primary/instance@realm) - params.kerberosServerPrimary = conf.get(ClientProperty.KERBEROS_SERVER_PRIMARY); - - return params; + this.kerberosServerPrimary = conf.get(ClientProperty.KERBEROS_SERVER_PRIMARY); } public Map<String,String> getSaslProperties() { @@ -211,10 +253,24 @@ public class SaslConnectionParams { return principal; } + /** + * The SASL mechanism to use for authentication + */ + public SaslMechanism getMechanism() { + return mechanism; + } + + /** + * The SASL callback handler for this mechanism, may be null. + */ + public CallbackHandler getCallbackHandler() { + return callbackHandler; + } + @Override public int hashCode() { HashCodeBuilder hcb = new HashCodeBuilder(23,29); - hcb.append(kerberosServerPrimary).append(saslProperties).append(qop.hashCode()).append(principal); + hcb.append(kerberosServerPrimary).append(saslProperties).append(qop.hashCode()).append(principal).append(mechanism).append(callbackHandler); return hcb.toHashCode(); } @@ -231,6 +287,16 @@ public class SaslConnectionParams { if (!principal.equals(other.principal)) { return false; } + if (!mechanism.equals(other.mechanism)) { + return false; + } + if (null == callbackHandler) { + if (null != other.callbackHandler) { + return false; + } + } else if (!callbackHandler.equals(other.callbackHandler)) { + return false; + } return saslProperties.equals(other.saslProperties); } @@ -238,6 +304,14 @@ public class SaslConnectionParams { return false; } + @Override + public String toString() { + StringBuilder sb = new StringBuilder(64); + sb.append("SaslConnectionParams[").append("kerberosServerPrimary=").append(kerberosServerPrimary).append(", qualityOfProtection=").append(qop); + sb.append(", principal=").append(principal).append(", mechanism=").append(mechanism).append(", callbackHandler=").append(callbackHandler).append("]"); + return sb.toString(); + } + public static String getDefaultRealm() { return defaultRealm; } http://git-wip-us.apache.org/repos/asf/accumulo/blob/2c983317/core/src/main/java/org/apache/accumulo/core/rpc/SaslDigestCallbackHandler.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/accumulo/core/rpc/SaslDigestCallbackHandler.java b/core/src/main/java/org/apache/accumulo/core/rpc/SaslDigestCallbackHandler.java new file mode 100644 index 0000000..901bec1 --- /dev/null +++ b/core/src/main/java/org/apache/accumulo/core/rpc/SaslDigestCallbackHandler.java @@ -0,0 +1,77 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.accumulo.core.rpc; + +import javax.security.auth.callback.CallbackHandler; + +import org.apache.commons.codec.binary.Base64; +import org.apache.hadoop.security.token.SecretManager; +import org.apache.hadoop.security.token.SecretManager.InvalidToken; +import org.apache.hadoop.security.token.TokenIdentifier; + +/** + * Common serialization methods across the client and server callback handlers for SASL. Serialization and deserialization methods must be kept in sync. + */ +public abstract class SaslDigestCallbackHandler implements CallbackHandler { + + /** + * Encode the serialized {@link TokenIdentifier} into a {@link String}. + * + * @param identifier + * The serialized identifier + * @see #decodeIdentifier(String) + */ + public String encodeIdentifier(byte[] identifier) { + return new String(Base64.encodeBase64(identifier)); + } + + /** + * Encode the token password into a character array. + * + * @param password + * The token password + * @see #getPassword(SecretManager, TokenIdentifier) + */ + public char[] encodePassword(byte[] password) { + return new String(Base64.encodeBase64(password)).toCharArray(); + } + + /** + * Generate the password from the provided {@link SecretManager} and {@link TokenIdentifier}. + * + * @param secretManager + * The server SecretManager + * @param tokenid + * The TokenIdentifier from the client + * @see #encodePassword(byte[]) + */ + public <T extends TokenIdentifier> char[] getPassword(SecretManager<T> secretManager, T tokenid) throws InvalidToken { + return encodePassword(secretManager.retrievePassword(tokenid)); + } + + /** + * Decode the encoded {@link TokenIdentifier} into bytes suitable to reconstitute the identifier. + * + * @param identifier + * The encoded, serialized {@link TokenIdentifier} + * @see #encodeIdentifier(byte[]) + */ + public byte[] decodeIdentifier(String identifier) { + return Base64.decodeBase64(identifier.getBytes()); + } + +} http://git-wip-us.apache.org/repos/asf/accumulo/blob/2c983317/core/src/main/java/org/apache/accumulo/core/rpc/ThriftUtil.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/accumulo/core/rpc/ThriftUtil.java b/core/src/main/java/org/apache/accumulo/core/rpc/ThriftUtil.java index d880fb3..51dd5ba 100644 --- a/core/src/main/java/org/apache/accumulo/core/rpc/ThriftUtil.java +++ b/core/src/main/java/org/apache/accumulo/core/rpc/ThriftUtil.java @@ -36,6 +36,7 @@ import org.apache.accumulo.core.client.impl.ClientExec; import org.apache.accumulo.core.client.impl.ClientExecReturn; import org.apache.accumulo.core.client.impl.ThriftTransportPool; import org.apache.accumulo.core.client.impl.thrift.ThriftSecurityException; +import org.apache.accumulo.core.rpc.SaslConnectionParams.SaslMechanism; import org.apache.accumulo.core.tabletserver.thrift.TabletClientService; import org.apache.accumulo.core.util.UtilWaitThread; import org.apache.hadoop.security.UserGroupInformation; @@ -65,7 +66,7 @@ public class ThriftUtil { private static final TFramedTransport.Factory transportFactory = new TFramedTransport.Factory(Integer.MAX_VALUE); private static final Map<Integer,TTransportFactory> factoryCache = new HashMap<Integer,TTransportFactory>(); - public static final String GSSAPI = "GSSAPI"; + public static final String GSSAPI = "GSSAPI", DIGEST_MD5 = "DIGEST-MD5"; /** * An instance of {@link TraceProtocolFactory} @@ -252,7 +253,7 @@ public class ThriftUtil { * RPC options */ public static TTransport createTransport(HostAndPort address, ClientContext context) throws TException { - return createClientTransport(address, (int) context.getClientTimeoutInMillis(), context.getClientSslParams(), context.getClientSaslParams()); + return createClientTransport(address, (int) context.getClientTimeoutInMillis(), context.getClientSslParams(), context.getSaslParams()); } /** @@ -345,11 +346,14 @@ public class ThriftUtil { // Is this pricey enough that we want to cache it? final String hostname = InetAddress.getByName(address.getHostText()).getCanonicalHostName(); - log.trace("Opening transport to server as {} to {}/{}", currentUser, saslParams.getKerberosServerPrimary(), hostname); + final SaslMechanism mechanism = saslParams.getMechanism(); + + log.trace("Opening transport to server as {} to {}/{} using {}", currentUser, saslParams.getKerberosServerPrimary(), hostname, mechanism); // Create the client SASL transport using the information for the server // Despite the 'protocol' argument seeming to be useless, it *must* be the primary of the server being connected to - transport = new TSaslClientTransport(GSSAPI, null, saslParams.getKerberosServerPrimary(), hostname, saslParams.getSaslProperties(), null, transport); + transport = new TSaslClientTransport(mechanism.getMechanismName(), null, saslParams.getKerberosServerPrimary(), hostname, + saslParams.getSaslProperties(), saslParams.getCallbackHandler(), transport); // Wrap it all in a processor which will run with a doAs the current user transport = new UGIAssumingTransport(transport, currentUser); http://git-wip-us.apache.org/repos/asf/accumulo/blob/2c983317/core/src/main/java/org/apache/accumulo/core/security/AuthenticationTokenIdentifier.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/accumulo/core/security/AuthenticationTokenIdentifier.java b/core/src/main/java/org/apache/accumulo/core/security/AuthenticationTokenIdentifier.java new file mode 100644 index 0000000..0b671d8 --- /dev/null +++ b/core/src/main/java/org/apache/accumulo/core/security/AuthenticationTokenIdentifier.java @@ -0,0 +1,210 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.accumulo.core.security; + +import static com.google.common.base.Preconditions.checkNotNull; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; +import java.nio.ByteBuffer; + +import org.apache.accumulo.core.client.admin.DelegationTokenConfig; +import org.apache.accumulo.core.security.thrift.TAuthenticationTokenIdentifier; +import org.apache.accumulo.core.util.ThriftMessageUtil; +import org.apache.commons.lang.builder.HashCodeBuilder; +import org.apache.hadoop.io.Text; +import org.apache.hadoop.security.UserGroupInformation; +import org.apache.hadoop.security.token.Token; +import org.apache.hadoop.security.token.TokenIdentifier; + +/** + * Implementation that identifies the underlying {@link Token} for Accumulo. + */ +public class AuthenticationTokenIdentifier extends TokenIdentifier { + public static final Text TOKEN_KIND = new Text("ACCUMULO_AUTH_TOKEN"); + + private TAuthenticationTokenIdentifier impl = null; + private DelegationTokenConfig cfg = null; + + public AuthenticationTokenIdentifier() { + // noop for Writable + } + + public AuthenticationTokenIdentifier(String principal) { + this(principal, null); + } + + public AuthenticationTokenIdentifier(String principal, DelegationTokenConfig cfg) { + checkNotNull(principal); + impl = new TAuthenticationTokenIdentifier(principal); + this.cfg = cfg; + } + + public AuthenticationTokenIdentifier(String principal, int keyId, long issueDate, long expirationDate, String instanceId) { + checkNotNull(principal); + impl = new TAuthenticationTokenIdentifier(principal); + impl.setKeyId(keyId); + impl.setIssueDate(issueDate); + impl.setExpirationDate(expirationDate); + impl.setInstanceId(instanceId); + } + + public AuthenticationTokenIdentifier(AuthenticationTokenIdentifier identifier) { + checkNotNull(identifier); + impl = new TAuthenticationTokenIdentifier(identifier.getThriftIdentifier()); + } + + public AuthenticationTokenIdentifier(TAuthenticationTokenIdentifier identifier) { + checkNotNull(identifier); + impl = new TAuthenticationTokenIdentifier(identifier); + } + + public void setKeyId(int keyId) { + impl.setKeyId(keyId); + } + + public int getKeyId() { + checkNotNull(impl, "Identifier not initialized"); + return impl.getKeyId(); + } + + public void setIssueDate(long issueDate) { + checkNotNull(impl, "Identifier not initialized"); + impl.setIssueDate(issueDate); + } + + public long getIssueDate() { + checkNotNull(impl, "Identifier not initialized"); + return impl.getIssueDate(); + } + + public void setExpirationDate(long expirationDate) { + checkNotNull(impl, "Identifier not initialized"); + impl.setExpirationDate(expirationDate); + } + + public long getExpirationDate() { + checkNotNull(impl, "Identifier not initialized"); + return impl.getExpirationDate(); + } + + public void setInstanceId(String instanceId) { + checkNotNull(impl, "Identifier not initialized"); + impl.setInstanceId(instanceId); + } + + public String getInstanceId() { + checkNotNull(impl, "Identifier not initialized"); + return impl.getInstanceId(); + } + + public TAuthenticationTokenIdentifier getThriftIdentifier() { + checkNotNull(impl); + return impl; + } + + /** + * A configuration from the requesting user, may be null. + */ + public DelegationTokenConfig getConfig() { + return cfg; + } + + @Override + public void write(DataOutput out) throws IOException { + if (null != impl) { + ThriftMessageUtil msgUtil = new ThriftMessageUtil(); + ByteBuffer serialized = msgUtil.serialize(impl); + out.writeInt(serialized.limit()); + out.write(serialized.array(), serialized.arrayOffset(), serialized.limit()); + } else { + out.writeInt(0); + } + } + + @Override + public void readFields(DataInput in) throws IOException { + int length = in.readInt(); + if (length > 0) { + ThriftMessageUtil msgUtil = new ThriftMessageUtil(); + byte[] serialized = new byte[length]; + in.readFully(serialized); + impl = new TAuthenticationTokenIdentifier(); + msgUtil.deserialize(serialized, impl); + } + } + + @Override + public Text getKind() { + return TOKEN_KIND; + } + + @Override + public UserGroupInformation getUser() { + if (null != impl && impl.isSetPrincipal()) { + return UserGroupInformation.createRemoteUser(impl.getPrincipal()); + } + return null; + } + + @Override + public int hashCode() { + if (null == impl) { + return 0; + } + HashCodeBuilder hcb = new HashCodeBuilder(7, 11); + if (impl.isSetPrincipal()) { + hcb.append(impl.getPrincipal()); + } + if (impl.isSetKeyId()) { + hcb.append(impl.getKeyId()); + } + if (impl.isSetIssueDate()) { + hcb.append(impl.getIssueDate()); + } + if (impl.isSetExpirationDate()) { + hcb.append(impl.getExpirationDate()); + } + if (impl.isSetInstanceId()) { + hcb.append(impl.getInstanceId()); + } + return hcb.toHashCode(); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(128); + sb.append("AuthenticationTokenIdentifier(").append(impl).append(")"); + return sb.toString(); + } + + @Override + public boolean equals(Object o) { + if (null == o) { + return false; + } + if (o instanceof AuthenticationTokenIdentifier) { + AuthenticationTokenIdentifier other = (AuthenticationTokenIdentifier) o; + if (null == impl) { + return null == other.impl; + } + return impl.equals(other.impl); + } + return false; + } +} http://git-wip-us.apache.org/repos/asf/accumulo/blob/2c983317/core/src/main/java/org/apache/accumulo/core/security/SystemPermission.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/accumulo/core/security/SystemPermission.java b/core/src/main/java/org/apache/accumulo/core/security/SystemPermission.java index b998179..a1df5dc 100644 --- a/core/src/main/java/org/apache/accumulo/core/security/SystemPermission.java +++ b/core/src/main/java/org/apache/accumulo/core/security/SystemPermission.java @@ -37,7 +37,8 @@ public enum SystemPermission { SYSTEM((byte) 7), CREATE_NAMESPACE((byte) 8), DROP_NAMESPACE((byte) 9), - ALTER_NAMESPACE((byte) 10); + ALTER_NAMESPACE((byte) 10), + OBTAIN_DELEGATION_TOKEN((byte) 11); private byte permID;