All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.mariadb.jdbc.internal.com.send.SendHandshakeResponsePacket Maven / Gradle / Ivy

The newest version!
/*
 *
 * MariaDB Client for Java
 *
 * Copyright (c) 2012-2014 Monty Program Ab.
 * Copyright (c) 2015-2017 MariaDB Ab.
 *
 * This library is free software; you can redistribute it and/or modify it under
 * the terms of the GNU Lesser General Public License as published by the Free
 * Software Foundation; either version 2.1 of the License, or (at your option)
 * any later version.
 *
 * This library is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
 * for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License along
 * with this library; if not, write to Monty Program Ab [email protected].
 *
 * This particular MariaDB Client for Java file is work
 * derived from a Drizzle-JDBC. Drizzle-JDBC file which is covered by subject to
 * the following copyright and notice provisions:
 *
 * Copyright (c) 2009-2011, Marcus Eriksson
 *
 * 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.
 *
 * Redistributions in binary form must reproduce 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 the driver nor the names of its contributors may not be
 * used to endorse or promote products derived from this software without specific
 * prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS  AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
 * OF SUCH DAMAGE.
 *
 */

package org.mariadb.jdbc.internal.com.send;

import org.mariadb.jdbc.MariaDbDatabaseMetaData;
import org.mariadb.jdbc.internal.MariaDbServerCapabilities;
import org.mariadb.jdbc.internal.com.read.Buffer;
import org.mariadb.jdbc.internal.io.output.PacketOutputStream;
import org.mariadb.jdbc.internal.protocol.authentication.DefaultAuthenticationProvider;
import org.mariadb.jdbc.internal.util.Options;
import org.mariadb.jdbc.internal.util.PidFactory;
import org.mariadb.jdbc.internal.util.Utils;
import org.mariadb.jdbc.internal.util.constant.Version;

import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import java.util.StringTokenizer;

/**
 * 4                            client_flags 4                            max_packet_size 1 charset_number 23 (filler)
 * always 0x00... n (Null-Terminated String)   user n (Length Coded Binary)      scramble_buff (1 + x bytes) 1 (filler)
 * always 0x00 n (Null-Terminated String) databasename
 * 

* client_flags: CLIENT_xxx options. The list of possible flag values is in the description of the Handshake * Initialisation Packet, for server_capabilities. For some of the bits, the server passed "what it's capable of". The * client leaves some of the bits on, adds others, and passes back to the server. One important flag is: whether * compression is desired. *

* max_packet_size: the maximum number of bytes in a stream for the client *

* charset_number: in the same domain as the server_language field that the server passes in the Handshake * Initialization stream. *

* user: identification *

* scramble_buff: the password, after encrypting using the scramble_buff contents passed by the server (see * "Password functions" section elsewhere in this document) if length is zero, no password was given *

* databasename: name of schema to use initially */ public class SendHandshakeResponsePacket { /** * Send handshake response packet. * * @param pos output stream * @param username user name * @param password password * @param database database name * @param clientCapabilities client capabilities * @param serverCapabilities server capabilities * @param serverLanguage server language (utf8 / utf8mb4 collation) * @param seed seed * @param packetSeq packet sequence * @param plugin plugin name * @param options user options * @throws IOException if socket exception occur * @see protocol documentation */ public static void send(final PacketOutputStream pos, String username, final String password, final String database, final long clientCapabilities, final long serverCapabilities, final byte serverLanguage, final byte[] seed, final byte packetSeq, final String plugin, final Options options) throws IOException { pos.startPacket(packetSeq); final byte[] authData; if (DefaultAuthenticationProvider.MYSQL_NATIVE_PASSWORD.equals(plugin) || "".equals(plugin)) { //CONJ-274 : permit connection mysql 5.1 db pos.permitTrace(false); try { authData = Utils.encryptPassword(password, seed, options.passwordCharacterEncoding); } catch (NoSuchAlgorithmException e) { throw new RuntimeException("Could not use SHA-1, failing", e); } } else if (DefaultAuthenticationProvider.MYSQL_CLEAR_PASSWORD.equals(plugin)) { pos.permitTrace(false); if (options.passwordCharacterEncoding != null && !options.passwordCharacterEncoding.isEmpty()) { authData = password.getBytes(options.passwordCharacterEncoding); } else { authData = password.getBytes(); } } else { authData = new byte[0]; } pos.writeInt((int) clientCapabilities); pos.writeInt(1024 * 1024 * 1024); pos.write(serverLanguage); //1 pos.writeBytes((byte) 0, 19); //19 pos.writeInt((int) (clientCapabilities >> 32)); //Maria extended flag if (username == null || "".equals(username)) username = System.getProperty("user.name"); //permit SSO pos.write(username.getBytes()); //strlen username pos.write((byte) 0); //1 if ((serverCapabilities & MariaDbServerCapabilities.PLUGIN_AUTH_LENENC_CLIENT_DATA) != 0) { pos.writeFieldLength(authData.length); pos.write(authData); } else if ((serverCapabilities & MariaDbServerCapabilities.SECURE_CONNECTION) != 0) { pos.write((byte) authData.length); pos.write(authData); } else { pos.write(authData); pos.write((byte) 0); } if ((serverCapabilities & MariaDbServerCapabilities.CONNECT_WITH_DB) != 0) { pos.write(database); pos.write((byte) 0); } if ((serverCapabilities & MariaDbServerCapabilities.PLUGIN_AUTH) != 0) { pos.write(plugin); pos.write((byte) 0); } if ((serverCapabilities & MariaDbServerCapabilities.CONNECT_ATTRS) != 0) { writeConnectAttributes(pos, options.connectionAttributes); } pos.flush(); pos.permitTrace(true); } private static void writeConnectAttributes(PacketOutputStream pos, String connectionAttributes) throws IOException { Buffer buffer = new Buffer(new byte[200]); buffer.writeStringLength("_client_name"); buffer.writeStringLength(MariaDbDatabaseMetaData.DRIVER_NAME); buffer.writeStringLength("_client_version"); buffer.writeStringLength(Version.version); buffer.writeStringLength("_os"); buffer.writeStringLength(System.getProperty("os.name")); String pid = PidFactory.getInstance().getPid(); if (pid != null) { buffer.writeStringLength("_pid"); buffer.writeStringLength(pid); } buffer.writeStringLength("_thread"); buffer.writeStringLength(Long.toString(Thread.currentThread().getId())); buffer.writeStringLength("_java_vendor"); buffer.writeStringLength(System.getProperty("java.vendor")); buffer.writeStringLength("_java_version"); buffer.writeStringLength(System.getProperty("java.version")); if (connectionAttributes != null) { StringTokenizer tokenizer = new StringTokenizer(connectionAttributes, ","); while (tokenizer.hasMoreTokens()) { String token = tokenizer.nextToken(); int separator = token.indexOf(":"); if (separator != -1) { buffer.writeStringLength(token.substring(0, separator)); buffer.writeStringLength(token.substring(separator + 1)); } else { buffer.writeStringLength(token); buffer.writeStringLength(""); } } } pos.writeFieldLength(buffer.position); pos.write(buffer.buf, 0, buffer.position); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy