imapext-2007
diff APOPtools/apopcall.c @ 1:28a55bc1110c
[mq]: imapext
author | yuuji@gentei.org |
---|---|
date | Mon, 14 Sep 2009 19:23:11 +0900 |
parents | |
children | d741b3ecc917 |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/APOPtools/apopcall.c Mon Sep 14 19:23:11 2009 +0900 1.3 @@ -0,0 +1,526 @@ 1.4 +#include <stdio.h> 1.5 +#include <stdlib.h> 1.6 +#include <string.h> 1.7 +#include <unistd.h> 1.8 +#include <sys/types.h> 1.9 +#include <sys/wait.h> 1.10 +#include <sys/stat.h> 1.11 +#include <pwd.h> 1.12 +#ifdef SHADOW_PASSWD 1.13 +#include <shadow.h> 1.14 +#endif 1.15 + 1.16 +#ifndef APOPPASSWD 1.17 +#define APOPPASSWD "/usr/local/bin/apoppasswd" 1.18 +#endif 1.19 +#ifndef APOPFILEBASE 1.20 +#define APOPFILEBASE ".apop" 1.21 +#endif 1.22 +#ifndef XADDR_DELIM 1.23 +#define XADDR_DELIM ('-') 1.24 +#endif 1.25 + 1.26 +char *myname; 1.27 + 1.28 +int ishexa(int c) { 1.29 + strchr("0123456789ABCDFabcdef", c) ? 1 : 0; 1.30 +} 1.31 + 1.32 +put_form(email, pass, new, new2, suffix, hidden, auth, force) 1.33 + char *email, *pass, *new, *new2, *suffix; 1.34 + int hidden, auth, force; 1.35 + /* auth = 0: old password 1.36 + 1: base addresse's mail password 1.37 + 2: unix password */ 1.38 +{ 1.39 + char *authtype[] = {"old", "base", "unix"}; 1.40 + char *var[] = {"email", "pass", "new", "new2", "auth", ""}; 1.41 + char *val[] = {email, pass, new, new2, authtype[auth]}; 1.42 + char *prm[] = {"", /* "ユーザ名", */ 1.43 + auth ? 1.44 + ((auth==1) 1.45 + ? "基本メイルアドレス用パスワード<br>Password for Basic Mail address" 1.46 + : "UNIXログインパスワード<br>UNIX login Password") 1.47 + : "古いメイルパスワード<br>Old Mail Password", 1.48 + "新しいメイルパスワード<br>New Mail Password", 1.49 + "新パスワードをもう一回(確認)<br>New Mail Password Again", 1.50 + ""}; 1.51 + int h=0, i; 1.52 + 1.53 + printf("<form method=POST action\"./%s\">\n", myname); 1.54 + printf(" <table border=1>\n"); 1.55 + for (i=0; var[i][0]; i++) { 1.56 + h = hidden || strstr("email,suffix,auth", var[i]); 1.57 + if (prm[i][0]) { 1.58 + printf("<tr><td>%s</td><td>", prm[i]); 1.59 + } else { 1.60 + } 1.61 + printf("<input name=%s %svalue=\"%s\" length=40 maxlength=40>\n", 1.62 + var[i], 1.63 + h ? "type=hidden " 1.64 + : (strstr(prm[i], "パスワード") ? "type=password " : "<br>"), 1.65 + val[i]); 1.66 + if (!strcmp(var[i], "suffix")) { 1.67 + /* ここでは suffix を入れさせない方がいいかも */ 1.68 + /* 表向きのメイルアドレスを表示しておく */ 1.69 + printf("%s", email); 1.70 + /* if (suffix[0]) { 1.71 + printf("-%s", suffix); 1.72 + } */ 1.73 + if (auth) 1.74 + printf("<br>(新規作成:New Account)"); 1.75 + } 1.76 + if (prm[i][0]) 1.77 + printf("</td></tr>"); 1.78 + printf("\n"); 1.79 + } 1.80 + 1.81 + printf("</table>\n"); 1.82 + if (force) 1.83 + printf("<input name=force type=hidden value=ON>\n"); 1.84 + if (auth) { 1.85 + char *a[] = {"basic", "unix"}; 1.86 + printf("<input type=hidden name=auth value=\"%s\">\n", a[auth-1]); 1.87 + } 1.88 + printf("<input name=OK value=OK type=submit>\n"); 1.89 + printf("<input name=RESET value=RESET type=reset>\n"); 1.90 + printf("</form>\n"); 1.91 + fflush(stdout); 1.92 +} 1.93 + 1.94 +char *decode(char *code) { 1.95 + int l=1+strlen(code); 1.96 + int i, c, d; 1.97 + char *ret = (char*)malloc(l*sizeof(char)); 1.98 + char *p = code; 1.99 + memset(ret, 0, l); 1.100 + for (i=0; i<strlen(code); i++) { 1.101 + if (code[i] == '+') code[i] = ' '; 1.102 + } 1.103 + while (code[0] && (p=strchr(code, '%')) 1.104 + && ishexa(*(p+1)) && ishexa(*(p+2))) { 1.105 + *(p++) = '\0'; 1.106 + strncat(ret, code, l); 1.107 + c = (islower(*p) ? toupper(*p) : *p) - '0'; 1.108 + p++; 1.109 + d = (islower(*p) ? toupper(*p) : *p) - '0'; 1.110 + if (c > 9) c -= ('A'-'9'-1); 1.111 + if (d > 9) d -= ('A'-'9'-1); 1.112 + ret[strlen(ret)] = c*16+d; 1.113 + code = p+1; 1.114 + } 1.115 + if (code[0]) strncat(ret, code, l); 1.116 + return ret; 1.117 +} 1.118 + 1.119 +#define BSIZE 8192 1.120 +char **decode_post() { 1.121 + char *buf = (char*)malloc(BSIZE*sizeof(char)); 1.122 + char **post, *p = buf; 1.123 + int n=0, i; 1.124 + post = (char**)calloc(1, sizeof(char*)); 1.125 + *buf = '\0'; 1.126 + fgets(buf, BSIZE, stdin); 1.127 + if (strchr("\n\r", buf[strlen(buf)-1])) /* chop */ 1.128 + buf[strlen(buf)-1] = '\0'; 1.129 + while (buf[0] && NULL != (p=strchr(buf, '&'))) { 1.130 + *p = '\0'; 1.131 + post[n] = (char*)malloc((p-buf+1)*sizeof(char)); 1.132 + strcpy(post[n], buf); 1.133 + n++; 1.134 + post = (char**)realloc(post, (1+n)*sizeof(char*)); 1.135 + buf = 1+p; 1.136 + } 1.137 + if (buf[0]) post[n++] = buf; 1.138 + /* decode URL encoded */ 1.139 + for (i=0; i < n; i++) { 1.140 + char *p; 1.141 + p=post[i]; 1.142 + post[i] = decode(p); 1.143 + } 1.144 + post[i] = ""; /* terminator */ 1.145 + return post; 1.146 +} 1.147 + 1.148 +void footer() { 1.149 + puts("</body>\n</html>"); 1.150 + fflush(stdout); 1.151 +} 1.152 + 1.153 +void fail() { 1.154 + printf("パスワード更新に失敗しました<br>\n"); 1.155 + printf("<a href=\"./\">やり直し</a><br>\n"); 1.156 + footer(); 1.157 + exit(1); 1.158 +} 1.159 +void success(char *email) { 1.160 + printf("<hr>メイルアカウント %s 用のパスワード更新は完了しました。<br>\n", 1.161 + email); 1.162 + footer(); 1.163 + exit(0); 1.164 +} 1.165 + 1.166 +int apopfile_existp(char *home, char *suffix, uid_t uid) { 1.167 + struct stat st; 1.168 + int s; 1.169 + int len = strlen(home) + 1 1.170 + + strlen(APOPFILEBASE) + strlen(suffix) + 3; 1.171 + char *apopfile = (char*)malloc(len); 1.172 + if (suffix[0]) { 1.173 + snprintf(apopfile, len, "%s/%s%c%s%c", 1.174 + home, APOPFILEBASE, XADDR_DELIM, suffix, 0); 1.175 + } else { 1.176 + snprintf(apopfile, len, "%s/%s%c", home, APOPFILEBASE, 0); 1.177 + } 1.178 + seteuid(uid); 1.179 + s = stat(apopfile, &st); 1.180 + seteuid(0); 1.181 + memset(apopfile, '\0', strlen(apopfile)); 1.182 + free(apopfile); 1.183 + return !s; 1.184 +} 1.185 + 1.186 +#ifndef QMAILCONTROL 1.187 +# define QMAILCONTROL "/var/qmail/control" 1.188 +#endif 1.189 +#ifndef MAILTMPLEN 1.190 +# define MAILTMPLEN 1024 1.191 +#endif 1.192 + 1.193 +/* Convert virtual domain user 1.194 + */ 1.195 +char* conv_virtualdomain(char *account) { 1.196 + char *dom = strchr(account, '@'), *p; 1.197 + char vd[MAILTMPLEN+1], rewrite[MAILTMPLEN+1], previous[MAILTMPLEN+1]; 1.198 + FILE *vdfd; 1.199 + int match=0; 1.200 + char buf[MAILTMPLEN+1], *s; 1.201 + snprintf(vd, MAILTMPLEN, "%s/%s", QMAILCONTROL, "virtualdomains"); 1.202 + if (NULL == dom) return account; 1.203 + dom++; /* set position of domain part beginning */ 1.204 + if (dom && NULL != (vdfd = fopen (vd, "r"))) { 1.205 + int l = strlen(dom); 1.206 + int L = strlen(account); 1.207 + while ((s=fgets(buf, MAILTMPLEN, vdfd))) { 1.208 + if (p=strchr(s, '#')) 1.209 + *p = '\0'; /* zap comments */ 1.210 + if (!strchr(buf, ':')) 1.211 + continue; 1.212 + while (s && (strrchr(s, '\n') || strrchr(s, '\r') || strrchr(s, ' '))) 1.213 + s[strlen(s)-1] = '\0'; 1.214 + if (!strncmp(account, s, L) && s[L] == ':' && s[L+1]) { /* user matches */ 1.215 + match = 3; 1.216 + snprintf(rewrite, MAILTMPLEN, "%s-%s", s+L+1, account); 1.217 + break; 1.218 + } 1.219 + if (!strncmp(dom, s, l) && s[l] == ':' && s[l+1]) { /* domain matches */ 1.220 + match = 2; 1.221 + snprintf(rewrite, MAILTMPLEN, "%s%c%s", s+l+1, XADDR_DELIM, account); 1.222 + continue; 1.223 + } 1.224 + if (match < 2 && s[0] == '.') { /* if domain described in wildcard */ 1.225 + if (p=strchr(s, ':')) { 1.226 + *p = '\0'; 1.227 + if (!strcmp(dom+(strlen(dom)-strlen(s)), s)) { 1.228 + if (match == 0 1.229 + || strlen(previous) < strlen(s)) { 1.230 + match = 1; 1.231 + strncpy(previous, s, MAILTMPLEN); 1.232 + snprintf(rewrite, MAILTMPLEN, "%s%c%s", p+1, XADDR_DELIM, account); 1.233 + } 1.234 + } 1.235 + } 1.236 + } 1.237 + } 1.238 + fclose(vdfd); 1.239 + if (match) { 1.240 + p = strchr(rewrite, '@'); 1.241 + /* fprintf(stderr, "m=%d, rwr=[%s]\n", match, rewrite); */ 1.242 + if (p) { 1.243 + *p = '\0'; 1.244 + } 1.245 + /* fprintf(stderr, "rwr=[%s]\n", rewrite); */ 1.246 + s = malloc(strlen(rewrite)+1); 1.247 + strncpy(s, rewrite, strlen(rewrite)+1); 1.248 + memset(vd, 0, sizeof(vd)); 1.249 + memset(rewrite, 0, sizeof(rewrite)); 1.250 + memset(previous, 0, sizeof(previous)); 1.251 + return s; 1.252 + } 1.253 + } 1.254 + /* Then, compare with locals */ 1.255 + snprintf(vd, MAILTMPLEN, "%s/%s", QMAILCONTROL, "locals"); 1.256 + if (NULL != (vdfd=fopen(vd, "r"))) { 1.257 + while (s=fgets(buf, MAILTMPLEN, vdfd)) { 1.258 + if (p=strchr(s, '#')) *p = '\0'; /* zap after comment mark # */ 1.259 + while (*s && (strrchr(s, '\r')||strrchr(s, '\n') 1.260 + ||strrchr(s, ' ')||strrchr(s, '\t'))) { 1.261 + *(s+strlen(s)-1) = '\0'; 1.262 + } 1.263 + while (*s && (*s == '\t' || *s == ' ')) s++; 1.264 + if (!strncmp(s, dom, strlen(s))) { /* matches with local domain */ 1.265 + int len = dom-account-1; 1.266 + p = (char*)malloc(len+1); 1.267 + memset(p, '\0', len+1); 1.268 + strncpy(p, account, len); 1.269 + return p; 1.270 + } 1.271 + } 1.272 + } 1.273 + return NULL; /* invalid domain */ 1.274 + /* return account; return itself */ 1.275 +} 1.276 + 1.277 +void apopcall(char **args) { 1.278 + int i=0, sc=0; 1.279 + pid_t pid; 1.280 + char *email="", *suffix="", *pass="", *new="", *new2 = "", *home=""; 1.281 + char buf[BUFSIZ], auth, *user; 1.282 + FILE *child, *result; 1.283 + while (args[i][0]) { 1.284 + /* printf("[%s]<br>\n", args[i]); */ 1.285 + if (!strncmp("email=", args[i], 6)) { 1.286 + email = args[i]+6; 1.287 + } else if (!strncmp("suffix=", args[i], 7)) { 1.288 + suffix = args[i]+7; 1.289 + } else if (!strncmp("pass=", args[i], 5)) { 1.290 + pass = args[i]+5; 1.291 + } else if (!strncmp("new=", args[i], 4)) { 1.292 + new = args[i]+4; 1.293 + } else if (!strncmp("new2=", args[i], 5)) { 1.294 + new2 = args[i]+5; 1.295 + } else if (!strncmp("auth=", args[i], 5)) { 1.296 + /* "this" or "base" or "unix" */ 1.297 + auth = args[i][5]; 1.298 + } 1.299 + i++; 1.300 + } 1.301 + /* Make a backup of original e-mail address */ 1.302 + /* user = (char*)malloc(1+strlen(email)); 1.303 + strcpy(user, email); 1.304 + */ 1.305 + user = conv_virtualdomain(email); 1.306 + if (NULL == user) { 1.307 + printf("そのようなドメインは無効です(%s)<br>\n", strchr(email, '@')); 1.308 + printf("入力したメイルアドレスを確認してやり直してください.<br>\n"); 1.309 + fail(); 1.310 + } 1.311 + if (strchr(user, XADDR_DELIM)) { 1.312 + char *p = malloc(1+strlen(user)); 1.313 + char *q = NULL; 1.314 + struct passwd *pwd; 1.315 + /* printf("user=[%s]<br>\n", user); */ 1.316 + 1.317 + memset(p, '\0', 1+strlen(user)); 1.318 + strcpy(p, user); 1.319 + while (!(pwd=getpwnam(p)) && (q=strrchr(p, XADDR_DELIM))) { 1.320 + fflush(stdout); 1.321 + *q = '\0'; 1.322 + } 1.323 + if (pwd && q) { 1.324 + q = user+(q-p)+1; 1.325 + user=p; 1.326 + suffix=q; 1.327 + } 1.328 + } 1.329 + if (user[0] && new[0] && new2[0]) { 1.330 + int tochild[2], toparent[2]; 1.331 + pid_t pid; 1.332 + int argc=0; 1.333 + char **argv; 1.334 + struct passwd *pswd; 1.335 + char *pstr; 1.336 + 1.337 + if (!(pswd=getpwnam(user))) { 1.338 + printf("Unkown user %s.\n", user); 1.339 + fflush(stdout); 1.340 + fail(); 1.341 + } 1.342 + pstr = pswd->pw_passwd; 1.343 +#ifdef SHADOW_PASSWD 1.344 + { struct spwd *ss = getspnam(user); 1.345 + pstr = (char*)ss->sp_pwdp; 1.346 + } 1.347 +#endif 1.348 + home=pswd->pw_dir; 1.349 + argv = (char**)calloc(4, sizeof(char*)); 1.350 + argv[argc++] = "apoppasswd"; 1.351 + argv[argc++] = "-s"; 1.352 + argv[argc++] = "-c"; 1.353 + /* if old password does not exist, 1.354 + then check UNIX password */ 1.355 +#if 0 1.356 + if (apopfile_existp(home, suffix, pswd->pw_uid)) { /* no apop-ext exists */ 1.357 + /* そのまま */ 1.358 + } else if (apopfile_existp(home, "", pswd->pw_uid)) {/* check base mail password */ 1.359 + argv = (char**)realloc(argv, (argc+2)*sizeof(char*)); 1.360 + argv[argc++] = "-b"; 1.361 + } 1.362 +#endif 1.363 + switch (auth) { 1.364 + case 'b': case 'B': 1.365 + if (apopfile_existp(home, "", pswd->pw_uid)) { 1.366 + argv = (char**)realloc(argv, (argc+2)*sizeof(char*)); 1.367 + argv[argc++] = "-b"; 1.368 + } else { 1.369 + printf("基本アドレスのパスワードファイルがありません<br>\n"); 1.370 + fail(); 1.371 + } 1.372 + break; 1.373 + case 'u': case 'U': 1.374 + if (strcmp(pstr, (char*)crypt(pass, pstr))) { 1.375 + printf("UNIX Password not correct.<br>\n"); 1.376 + /* printf("[%s]vs.[%s]<br>\n", 1.377 + pswd->pw_passwd, crypt(pass, pswd->pw_passwd)); */ 1.378 + printf("UNIXパスワードと一致しません.<br>\n"); 1.379 + fflush(stdout); 1.380 + fail(); 1.381 + } 1.382 + } 1.383 + 1.384 + if (strlen(new) < 8 || strlen(new2) < 8) { 1.385 + printf("New mail password must be more than 7 characters.<br>\n"); 1.386 + printf("メイルパスワードは8文字以上にしてください。<br>\n"); 1.387 + fflush(stdout); 1.388 + fail(); 1.389 + } 1.390 + if (suffix[0]) { 1.391 + argv = (char**)realloc(argv, (argc+3)*sizeof(char*)); 1.392 + argv[argc++] = "-e"; 1.393 + argv[argc++] = suffix; 1.394 + 1.395 + } 1.396 + argv[argc++] = NULL; 1.397 + if (setgid(pswd->pw_gid) || 0 != setuid(pswd->pw_uid)) { 1.398 + printf("Cannot switch to %s\n", user); 1.399 + printf("uid=%d, gid=%d<br>\n", pswd->pw_gid, pswd->pw_uid); 1.400 + printf("メイルパスワード変更サーバの設定不良の可能性があるので<br>\n"); 1.401 + printf("お手数ですがこの画面のコピーを添えてシステム管理者"); 1.402 + printf("まで御連絡下さい。<br>\n"); 1.403 + fflush(stdout); 1.404 + fail(); 1.405 + } 1.406 + 1.407 + /* OK, start apopasswd */ 1.408 + if (pipe(tochild)+pipe(toparent)) { 1.409 + printf("Cannot create pipe\n"); 1.410 + fail(); 1.411 + } 1.412 + if ((pid=fork()) > 0) { 1.413 + FILE *child = fdopen(tochild[1], "w"); 1.414 + close(tochild[0]); 1.415 + close(toparent[1]); 1.416 + fprintf(child, "PASS %s\nNEW %s\nNEW2 %s\n", 1.417 + pass, new, new2); 1.418 + fflush(child); 1.419 + fclose(child); 1.420 + 1.421 + } else if (pid == -1) { 1.422 + printf("Cannot fork\n"); 1.423 + fail(); 1.424 + } else { 1.425 + char *pe = malloc(6+strlen(pswd->pw_dir)); 1.426 + close(tochild[1]); 1.427 + close(toparent[0]); 1.428 + dup2(tochild[0], 0); 1.429 + dup2(toparent[1], 1); 1.430 + 1.431 + /* setuid section */ 1.432 + 1.433 + strcpy(pe, "HOME="); 1.434 + strcat(pe, pswd->pw_dir); 1.435 + if (putenv(pe)) { 1.436 + puts("ga-n! arichan gakkari<br>"); 1.437 + } 1.438 + execv(APOPPASSWD, argv); 1.439 + 1.440 + /* setuid section ends */ 1.441 + fprintf(stderr, "Cannot exec %s\n", APOPPASSWD); 1.442 + fail(); 1.443 + } 1.444 + result = fdopen(toparent[0], "r"); 1.445 + while (fgets(buf, BUFSIZ, result)) { 1.446 + printf("%s<br>", buf); 1.447 + fflush(stdout); 1.448 + if (strstr(buf, "Success!")) { 1.449 + printf("<br>Mail Password changed successfully!<br>\n"); 1.450 + sc++; 1.451 + break; 1.452 + } else if (strstr(buf, "mismatch")) { 1.453 + printf("二個入れた新パスワードが一致しません.<br>\n"); 1.454 + break; 1.455 + } else if (strstr(buf, "Illegal")) { 1.456 + printf("照合用パスワードが違います.<br>--\n"); 1.457 + break; 1.458 + } else if (strstr(buf, "does not exist")) { 1.459 + /* try_overwrite(user, pass, new, new2, suffix); */ 1.460 + if (suffix[0]) { 1.461 + printf("%s-%s", user, suffix); 1.462 + } else { 1.463 + printf("%s", user); 1.464 + } 1.465 + /* ここは来ないことになった(のはず) */ 1.466 + printf("というメイルアカウントは未作成です<br>\n"); 1.467 + printf("新規に作る場合はOKボタンをクリック\n"); 1.468 + put_form(email, pass, new, new2, suffix, 1, 0, 1); 1.469 + fflush(stdout); 1.470 + } 1.471 + } 1.472 + fclose(result); 1.473 + while (wait(0) != pid) {sleep(1);fputc('.', stderr);} 1.474 + if (sc) success(email); else fail(); 1.475 + } else if (user[0]) { 1.476 + struct passwd *pw = getpwnam(user); 1.477 + int auth=0; 1.478 + if (!pw) { 1.479 + printf("そのようなユーザはいません %s<br>\n", user); 1.480 + fail(); 1.481 + } 1.482 + home=pw->pw_dir; 1.483 + 1.484 + printf("%s というメイルアドレスの<br>\n", email); 1.485 + printf("メイル専用パスワードを変更します.<br>\n"); 1.486 + printf("メイルパスワードとUNIXパスワードの違いに気をつけてください.<br>\n"); 1.487 + printf("新パスワードは8文字以上にしてください.<br>\n"); 1.488 + printf("New password must be more than or equal to 8 characters.<br>\n"); 1.489 + if (apopfile_existp(home, suffix, pw->pw_uid)) { 1.490 + auth = 0; /* this password file */ 1.491 + printf("「古いメイルパスワード」には、現在<br>\n"); 1.492 + printf("<tt>%s</tt><br>\n", email); 1.493 + printf("を読むために指定しているパスワードを入力します。"); 1.494 + } else if (apopfile_existp(home, "", pw->pw_uid)) { 1.495 + auth = 1; /* basic mail address password */ 1.496 + printf("今回は本人認証として基本メイルアドレスのパスワードを"); 1.497 + printf("入力しますが、新しくパスワードを設定するのは<br>\n"); 1.498 + printf("<tt>%s</tt><br>\n", email); 1.499 + printf("用のパスワードです。基本メイルアドレスのパスワードは"); 1.500 + printf("変わりませんので注意してください。"); 1.501 + } else { 1.502 + auth = 2; /* UNIX login */ 1.503 + } 1.504 + put_form(email, "", "", "", suffix, 0, auth, 0); 1.505 + footer(); 1.506 + exit(0); 1.507 + } 1.508 + printf("user=[%s]\n", user); 1.509 +} 1.510 + 1.511 +int main(int argc, char* argv[]) { 1.512 + char *method = getenv("REQUEST_METHOD"); 1.513 + char **args; 1.514 + myname = argv[0]; 1.515 + if (method && strcmp(method, "POST") != 0) { 1.516 + printf("This program should be used in method:POST.\n"); 1.517 + fail(); 1.518 + } 1.519 + printf("Content-type: text/html; charset=EUC-JP\n\n"); 1.520 + printf("<html>\n<head><title>Change Password</title></head>\n"); 1.521 + printf("<body style=\"background: #f0ffff;\">\n"); 1.522 + if (getenv("SSL_CIPHER") && getenv("SSL_PROTOCOL")) { 1.523 + args = decode_post(); 1.524 + apopcall(args); 1.525 + } else { 1.526 + printf("This program can be used only via SSL connection.<br>\n"); 1.527 + printf("このユーティリティはSSL接続時のみ有効です.<br>\n"); 1.528 + } 1.529 +}