private void doAuthentication(PGStream pgStream, String user, String password, Logger logger) throws IOException, SQLException { // Now get the response from the backend, either an error message // or an authentication request while (true) { int beresp = pgStream.ReceiveChar(); switch (beresp) { case 'E': // An error occured, so pass the error message to the // user. // // The most common one to be thrown here is: // "User authentication failed" // int l_elen = pgStream.ReceiveInteger4(); if (l_elen > 30000) { // if the error length is > than 30000 we assume this is really a v2 protocol // server, so trigger fallback. throw new UnsupportedProtocolException(); } ServerErrorMessage errorMsg = new ServerErrorMessage(pgStream.ReceiveString(l_elen - 4), logger.getLogLevel()); if (logger.logDebug()) logger.debug(" <=BE ErrorMessage(" + errorMsg + ")"); throw new PSQLException(errorMsg); case 'R': // Authentication request. // Get the message length int l_msgLen = pgStream.ReceiveInteger4(); // Get the type of request int areq = pgStream.ReceiveInteger4(); // Process the request. switch (areq) { case AUTH_REQ_CRYPT: { byte[] rst = new byte[2]; rst[0] = (byte) pgStream.ReceiveChar(); rst[1] = (byte) pgStream.ReceiveChar(); String salt = new String(rst, 0, 2, "US-ASCII"); if (logger.logDebug()) logger.debug(" <=BE AuthenticationReqCrypt(salt='" + salt + "')"); if (password == null) throw new PSQLException( GT.tr( "The server requested password-based authentication, but no password was provided."), PSQLState.CONNECTION_REJECTED); String result = UnixCrypt.crypt(salt, password); byte[] encodedResult = result.getBytes("US-ASCII"); if (logger.logDebug()) logger.debug(" FE=> Password(crypt='" + result + "')"); pgStream.SendChar('p'); pgStream.SendInteger4(4 + encodedResult.length + 1); pgStream.Send(encodedResult); pgStream.SendChar(0); pgStream.flush(); break; } case AUTH_REQ_MD5: { byte[] md5Salt = pgStream.Receive(4); if (logger.logDebug()) { logger.debug( " <=BE AuthenticationReqMD5(salt=" + Utils.toHexString(md5Salt) + ")"); } if (password == null) throw new PSQLException( GT.tr( "The server requested password-based authentication, but no password was provided."), PSQLState.CONNECTION_REJECTED); byte[] digest = MD5Digest.encode(user, password, md5Salt); if (logger.logDebug()) { logger.debug(" FE=> Password(md5digest=" + new String(digest, "US-ASCII") + ")"); } pgStream.SendChar('p'); pgStream.SendInteger4(4 + digest.length + 1); pgStream.Send(digest); pgStream.SendChar(0); pgStream.flush(); break; } case AUTH_REQ_PASSWORD: { if (logger.logDebug()) { logger.debug(" <=BE AuthenticationReqPassword"); logger.debug(" FE=> Password(password=<not shown>)"); } if (password == null) throw new PSQLException( GT.tr( "The server requested password-based authentication, but no password was provided."), PSQLState.CONNECTION_REJECTED); byte[] encodedPassword = password.getBytes("US-ASCII"); pgStream.SendChar('p'); pgStream.SendInteger4(4 + encodedPassword.length + 1); pgStream.Send(encodedPassword); pgStream.SendChar(0); pgStream.flush(); break; } case AUTH_REQ_OK: if (logger.logDebug()) logger.debug(" <=BE AuthenticationOk"); return; // We're done. default: if (logger.logDebug()) logger.debug(" <=BE AuthenticationReq (unsupported type " + ((int) areq) + ")"); throw new PSQLException( GT.tr( "The authentication type {0} is not supported. Check that you have configured the pg_hba.conf file to include the client''s IP address or subnet, and that it is using an authentication scheme supported by the driver.", new Integer(areq)), PSQLState.CONNECTION_REJECTED); } break; default: throw new PSQLException( GT.tr("Protocol error. Session setup failed."), PSQLState.CONNECTION_UNABLE_TO_CONNECT); } } }
public void put(StoredBlock storedBlock, StoredUndoableBlock undoableBlock) throws BlockStoreException { maybeConnect(); // We skip the first 4 bytes because (on prodnet) the minimum target has 4 0-bytes byte[] hashBytes = new byte[28]; System.arraycopy(storedBlock.getHeader().getHash().getBytes(), 3, hashBytes, 0, 28); int height = storedBlock.getHeight(); byte[] transactions = null; byte[] txOutChanges = null; try { ByteArrayOutputStream bos = new ByteArrayOutputStream(); if (undoableBlock.getTxOutChanges() != null) { undoableBlock.getTxOutChanges().serializeToStream(bos); txOutChanges = bos.toByteArray(); } else { int numTxn = undoableBlock.getTransactions().size(); bos.write((int) (0xFF & (numTxn >> 0))); bos.write((int) (0xFF & (numTxn >> 8))); bos.write((int) (0xFF & (numTxn >> 16))); bos.write((int) (0xFF & (numTxn >> 24))); for (Transaction tx : undoableBlock.getTransactions()) tx.rimbitSerialize(bos); transactions = bos.toByteArray(); } bos.close(); } catch (IOException e) { throw new BlockStoreException(e); } try { if (log.isDebugEnabled()) log.debug("Looking for undoable block with hash: " + Utils.bytesToHexString(hashBytes)); PreparedStatement findS = conn.get().prepareStatement("select 1 from undoableBlocks where hash = ?"); findS.setBytes(1, hashBytes); ResultSet rs = findS.executeQuery(); if (rs.next()) { // We already have this output, update it. findS.close(); // Postgres insert-or-updates are very complex (and finnicky). This level of transaction // isolation // seems to work for rimbitj PreparedStatement s = conn.get() .prepareStatement( "UPDATE undoableBlocks SET txOutChanges=?, transactions=?" + " WHERE hash = ?"); s.setBytes(3, hashBytes); if (log.isDebugEnabled()) log.debug("Updating undoable block with hash: " + Utils.bytesToHexString(hashBytes)); if (transactions == null) { s.setBytes(1, txOutChanges); s.setNull(2, Types.BINARY); } else { s.setNull(1, Types.BINARY); s.setBytes(2, transactions); } s.executeUpdate(); s.close(); return; } PreparedStatement s = conn.get() .prepareStatement( "INSERT INTO undoableBlocks(hash, height, txOutChanges, transactions)" + " VALUES(?, ?, ?, ?)"); s.setBytes(1, hashBytes); s.setInt(2, height); if (log.isDebugEnabled()) log.debug( "Inserting undoable block with hash: " + Utils.bytesToHexString(hashBytes) + " at height " + height); if (transactions == null) { s.setBytes(3, txOutChanges); s.setNull(4, Types.BINARY); } else { s.setNull(3, Types.BINARY); s.setBytes(4, transactions); } s.executeUpdate(); s.close(); try { putUpdateStoredBlock(storedBlock, true); } catch (SQLException e) { throw new BlockStoreException(e); } } catch (SQLException e) { if (!e.getSQLState().equals(POSTGRES_DUPLICATE_KEY_ERROR_CODE)) throw new BlockStoreException(e); } }