initial public commit

This commit is contained in:
2021-09-06 17:46:59 +03:00
commit b744b08829
824 changed files with 91593 additions and 0 deletions

View File

@ -0,0 +1,93 @@
/*-
* ~~~~~~licensing~~~~~~
* htpasswd
* ==========
* Copyright (C) 2020 - 2021 EmDev LLC
* ==========
* Licensed 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.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.esb.system.auth.basic.htpasswd;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import ru.entaxy.esb.system.auth.basic.htpasswd.entity.Htpasswd;
import ru.entaxy.esb.system.auth.basic.jpa.api.entity.BasicAuthAccount;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.NoSuchAlgorithmException;
import java.util.List;
public class HtpasswdGenerator {
private static final Log LOG = LogFactory.getLog(HtpasswdGenerator.class);
private String checkSumFileName;
public Htpasswd htpasswd;
public void generateHtpasswd(List<BasicAuthAccount> accounts, String salt) throws IOException, NoSuchAlgorithmException {
htpasswd.setMasterSalt(salt);
htpasswd.prepare(accounts);
createFile();
}
private void createFile() throws IOException {
String content = htpasswd.toString();
LOG.trace("HTTPASSWD " + content);
String storeFolder = htpasswd.getDirectory();
File folder = new File(storeFolder);
folder.mkdirs();
File htpasswdFile = new File(folder.getAbsolutePath() + File.separator + htpasswd.getFileName());
Path path = Paths.get(htpasswdFile.getAbsolutePath());
Files.write(path, content.getBytes());
String checkSum = calculateCheckSum(path);
File checkSumFile = new File(folder.getAbsolutePath() + File.separator + checkSumFileName);
path = Paths.get(checkSumFile.getAbsolutePath());
Files.write(path, checkSum.getBytes());
}
private String calculateCheckSum(Path path) throws IOException {
String md5;
try (InputStream is = Files.newInputStream(path)) {
md5 = DigestUtils.md5Hex(is);
}
return md5;
}
public Htpasswd getHtpasswd() {
return htpasswd;
}
public void setHtpasswd(Htpasswd htpasswd) {
this.htpasswd = htpasswd;
}
public String getCheckSumFileName() {
return checkSumFileName;
}
public void setCheckSumFileName(String checkSumFileName) {
this.checkSumFileName = checkSumFileName;
}
}

View File

@ -0,0 +1,98 @@
/*-
* ~~~~~~licensing~~~~~~
* htpasswd
* ==========
* Copyright (C) 2020 - 2021 EmDev LLC
* ==========
* Licensed 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.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.esb.system.auth.basic.htpasswd.entity;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import ru.entaxy.esb.system.auth.basic.jpa.api.entity.BasicAuthAccount;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.List;
public class Htpasswd {
private static final Log LOG = LogFactory.getLog(Htpasswd.class);
private String directory;
private String fileName;
private String masterSalt = null;
private final List<HtpasswdEntry> entries = new ArrayList<>();
public Htpasswd() {
}
public void prepare(List<BasicAuthAccount> accounts) throws NoSuchAlgorithmException {
if (masterSalt == null || masterSalt.isEmpty()) {
throw new IllegalArgumentException("masterSalt not setted!");
}
if (accounts != null && accounts.size() > 0) {
entries.clear();
for (BasicAuthAccount account : accounts) {
entries.add(new HtpasswdEntry(
account.getLogin(),
account.getPasswordHash(),
masterSalt,
account.getEncryptionAlgorithm().getAlgorithmName()));
}
}
}
public void addString(String login, String passwordHash, String encryptionAlgorithm) throws NoSuchAlgorithmException {
entries.add(new HtpasswdEntry(
login,
passwordHash,
masterSalt,
encryptionAlgorithm));
}
public String getDirectory() {
return directory;
}
public void setDirectory(String directory) {
this.directory = directory;
}
public String getFileName() {
return fileName;
}
public void setFileName(String fileName) {
this.fileName = fileName;
}
public String getMasterSalt() {
return masterSalt;
}
public void setMasterSalt(String masterSalt) {
this.masterSalt = masterSalt;
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
for (HtpasswdEntry entry : entries) {
builder.append(entry.toString());
}
return builder.toString();
}
}

View File

@ -0,0 +1,86 @@
/*-
* ~~~~~~licensing~~~~~~
* htpasswd
* ==========
* Copyright (C) 2020 - 2021 EmDev LLC
* ==========
* Licensed 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.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.esb.system.auth.basic.htpasswd.entity;
import org.apache.commons.codec.binary.Base64;
import ru.entaxy.esb.system.auth.basic.jpa.api.entity.field.EncryptionAlgorithm;
import java.nio.charset.StandardCharsets;
import java.security.NoSuchAlgorithmException;
public class HtpasswdEntry {
private static final String APR1_PREFIX = "$apr1$";
private static final String SHA512_PREFIX = "$6$";
private static final String SALTED_SHA1_PREFIX = "{SSHA}";
private static final String PLAIN_PREFIX = "{PLAIN}";
private static final String COLON = ":";
private final String resultLine;
public HtpasswdEntry(String login, String passwordHash, String salt, String encryptionAlgorithm) throws NoSuchAlgorithmException {
this(login, passwordHash, salt, encryptionAlgorithm, true);
}
public HtpasswdEntry(String login, String passwordHash, String salt, String encryptionAlgorithm, boolean addLineSeparator) throws NoSuchAlgorithmException {
StringBuilder content = new StringBuilder();
content.append(login).append(COLON);
if (EncryptionAlgorithm.MD5.equalsName(encryptionAlgorithm)) {
content
.append(APR1_PREFIX)
.append(salt)
.append("$")
.append(passwordHash);
} else if (EncryptionAlgorithm.SHA1.equalsName(encryptionAlgorithm)) {
content.append(SALTED_SHA1_PREFIX);
byte[] digest = Base64.decodeBase64(passwordHash);
byte[] saltBytes = salt.getBytes(StandardCharsets.UTF_8);
int l1 = digest.length;
int l2 = saltBytes.length;
byte[] resultArr = new byte[l1 + l2];
System.arraycopy(digest, 0, resultArr, 0, l1);
System.arraycopy(saltBytes, 0, resultArr, l1, l2);
content.append(Base64.encodeBase64String(resultArr));
} else if (EncryptionAlgorithm.SHA512.equalsName(encryptionAlgorithm)) {
content
.append(SHA512_PREFIX)
.append(salt)
.append("$")
.append(passwordHash);
} else if (EncryptionAlgorithm.PLAIN.equalsName(encryptionAlgorithm)) {
content
.append(PLAIN_PREFIX)
.append(passwordHash);
} else {
content.append(passwordHash);
}
content.append(System.lineSeparator());
this.resultLine = content.toString();
}
@Override
public String toString() {
return resultLine;
}
}

View File

@ -0,0 +1,43 @@
/*-
* ~~~~~~licensing~~~~~~
* htpasswd
* ==========
* Copyright (C) 2020 - 2021 EmDev LLC
* ==========
* Licensed 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.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.esb.system.auth.basic.htpasswd.rest;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import java.io.File;
@Path("/")
public class HtpasswdService {
@GET
@Produces("application/octet-stream")
public File getFile() {
return null;
}
@GET
@Path("/checksum")
@Produces("plain/text")
public String getCheckSum() {
return null;
}
}

View File

@ -0,0 +1,95 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~~~~~~licensing~~~~~~
htpasswd
==========
Copyright (C) 2020 - 2021 EmDev LLC
==========
Licensed 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.
~~~~~~/licensing~~~~~~
-->
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:cm="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.1.0"
xmlns:camelcxf="http://camel.apache.org/schema/blueprint/cxf"
xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0 https://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd">
<cm:property-placeholder persistent-id="ru.entaxy.esb.system.basic_auth.htpasswd" update-strategy="reload">
<cm:default-properties>
<cm:property name="htpasswd.file.directory" value="securityTest"/>
<cm:property name="htpasswd.file.name" value="htpasswd"/>
<cm:property name="htpasswd.file.checksum" value="MD5.md5"/>
<cm:property name="htpasswd.service.host" value="http://localhost"/>
<cm:property name="htpasswd.service.port" value="9091"/>
<cm:property name="htpasswd.service.root.path" value="/htpasswd"/>
</cm:default-properties>
</cm:property-placeholder>
<bean id="htpasswd" class="ru.entaxy.esb.system.auth.basic.htpasswd.entity.Htpasswd">
<property name="fileName" value="${htpasswd.file.name}"/>
<property name="directory" value="${htpasswd.file.directory}"/>
</bean>
<service ref="htpasswdGenerator" interface="ru.entaxy.esb.system.auth.basic.htpasswd.HtpasswdGenerator"/>
<bean id="htpasswdGenerator" class="ru.entaxy.esb.system.auth.basic.htpasswd.HtpasswdGenerator">
<property name="htpasswd" ref="htpasswd"/>
<property name="checkSumFileName" value="${htpasswd.file.checksum}"/>
</bean>
<!-- <reference id="phaseInterceptor" -->
<!-- interface="org.apache.cxf.phase.PhaseInterceptor" -->
<!-- filter="(type=system)" -->
<!-- timeout="30000" -->
<!-- availability="optional"/> -->
<!-- <cxf:bus id="entaxy"> -->
<!-- <cxf:inInterceptors> -->
<!-- <ref component-id="phaseInterceptor"/> -->
<!-- </cxf:inInterceptors> -->
<!-- </cxf:bus> -->
<camelcxf:rsServer id="rsServer"
address="${htpasswd.service.host}:${htpasswd.service.port}${htpasswd.service.root.path}"
serviceClass="ru.entaxy.esb.system.auth.basic.htpasswd.rest.HtpasswdService"
loggingFeatureEnabled="false" loggingSizeLimit="20"/>
<camelContext id="htpasswd-camel-context" xmlns="http://camel.apache.org/schema/blueprint">
<route id="htpasswdServiceRouter">
<from uri="cxfrs:bean:rsServer?bindingStyle=SimpleConsumer"/>
<log message="Htpassed service operation ${header.operationName}" loggingLevel="DEBUG"/>
<toD uri="direct:${header.operationName}"/>
</route>
<route id="file">
<from uri="direct:getFile"/>
<log message="Request direct:getFile: type=${header.type}, active=${header.active}, customerData=${body}"/>
<pollEnrich timeout="0">
<simple>file:${properties:htpasswd.file.directory}?noop=true&amp;fileName=${properties:htpasswd.file.name}&amp;idempotent=false</simple>
</pollEnrich>
<convertBodyTo type="String"/>
</route>
<route id="checkSum">
<from uri="direct:getCheckSum"/>
<log message="Request direct:getCheckSum: type=${header.type}, active=${header.active}, customerData=${body}"/>
<pollEnrich timeout="0">
<simple>file:${properties:htpasswd.file.directory}?noop=true&amp;fileName=${properties:htpasswd.file.checksum}&amp;idempotent=false</simple>
</pollEnrich>
<convertBodyTo type="String"/>
</route>
</camelContext>
</blueprint>

View File

@ -0,0 +1,67 @@
###
# ~~~~~~licensing~~~~~~
# htpasswd
# ==========
# Copyright (C) 2020 - 2021 EmDev LLC
# ==========
# Licensed 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.
# ~~~~~~/licensing~~~~~~
###
# !/bin/sh
KARAF_HOST_NAMES=("http://192.168.122.93:9091" "http://192.168.122.94:9091")
HTPASSWD_PATH=/htpasswd
CHECKSUM_PATH=$HTPASSWD_PATH/checksum
HTPASSWD_STORAGE=/etc/nginx/htpasswd
LOGFILE="htpasswd-sync.log"
TIMESTAMP=`date "+%Y-%m-%d %H:%M:%S"`
currentChecksum=`md5sum $HTPASSWD_STORAGE | awk '{ print $1 }'`
log(){
echo "$TIMESTAMP $1" >> $LOGFILE
}
#download actual checksum from karaf
for actualHost in ${KARAF_HOST_NAMES[*]}; do
wget -O checksum $actualHost$CHECKSUM_PATH
newChecksum=`cat checksum`
rm checksum
if [[ -n $newChecksum ]]
then
log "checksum received from host $actualHost"
break
else
log "host $actualHost did not give checksum data"
fi
done
log "newChecksum $newChecksum"
log "currentChecksum $currentChecksum"
if [[ -n $newChecksum ]] && { [[ -z $currentChecksum ]] || [ $currentChecksum != $newChecksum ]; };
then
wget -O htpasswd $actualHost$HTPASSWD_PATH
sudo mv htpasswd $HTPASSWD_STORAGE
sudo chmod 644 $HTPASSWD_STORAGE
sudo chown root:root $HTPASSWD_STORAGE
sudo systemctl reload nginx
log ">>>>>>>>>>>>>>>>> Htpasswd updated"
else
if [[ -n $newChecksum ]]
then
log ">>>>>>>>>>>>>>>>> Htpasswd is up to date"
else
log ">>>>>>>>>>>>>>>>> Script finished with error: new checksum not received!"
#error action
fi
fi